swiftdownloadfirebase-storagetmp

Downloading Firebase Storage Files Device Issue


I am trying to download a word document from Firebase storage. On the simulator everything is working as expected. Yet on my device, I get the following error:

Optional(Error Domain=FIRStorageErrorDomain Code=-13000 "An unknown error occurred, please check the server response." UserInfo={object=26 October 2016.docx, bucket=app.appspot.com, NSLocalizedDescription=An unknown error occurred, please check the server response., ResponseErrorDomain=NSCocoaErrorDomain, NSFilePath=/tmp/bulletin, NSUnderlyingError=0x1702590b0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}, ResponseErrorCode=513})

Other posts I have been looking at do not seem to give me a working answer, and all I know is that there is an issue with file permissions, even though I am using the recommended directory (tmp).

This is the code for downloading the file

 let Ref_Bulletin = Bulletin.referenceForURL("gs:/app.appspot.com/Bulletin/\(Today.stringFromDate(NSDate())).docx")

    // Create local filesystem URL
    let localURL: NSURL! = NSURL(string: "file:///tmp/today.docx")


        // Download to the local filesystem
        let downloadTask = Ref_Bulletin.writeToFile(localURL) { (URL, error) -> Void in
            if (error != nil) {
                print(error.debugDescription)
                // Uh-oh, an error occurred!
            } else {
                print("Working As Expected")
                self.Web_View.loadRequest(NSURLRequest(URL: localURL))
            }

So what is causing this problem and how do I fix it?

Update:

So I tried to create the directory but I am being told that I don't have permission even though the documentation says I can write to the tmp.

Unable to create directory Error Domain=NSCocoaErrorDomain Code=513 "You don’t have permission to save the file “today.docx” in the folder “h”." UserInfo={NSFilePath=/tmp/h/today.docx, NSUnderlyingError=0x1702498a0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}

This is the code for creating the directory:

 do {
        try NSFileManager.defaultManager().createDirectoryAtPath(localURL.path!, withIntermediateDirectories: true, attributes: nil)
    } catch let error as NSError {
        NSLog("Unable to create directory \(error.debugDescription)")
    }

Solution

  • I assume that the issue here is that the tmp and Documents directories don't actually live at /tmp and /Documents (for instance, it appears as though /Documents is actually /User/Documents, which is actually /private/var/mobile/Documents, see: https://www.theiphonewiki.com/wiki/)

    You'll want to make sure you're creating your File URLs based off where the system thinks those directories are, rather than a string:

    NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory()];
    NSURL *fileURL = [[tmpDirURL URLByAppendingPathComponent:@"my_file"] URLByAppendingPathExtension:@"txt"];
    

    Or similar for NSDocumentDirectory. As for why that works on the simulator: I assume this is because sandboxing on the simulator doesn't work the same way as a real device, and that /tmp is apparently a valid location you can write to (though likely not the one you want to be writing two, as evidenced by iOS throwing a hissy fit when you try to do it on a real device).