【问题标题】:How do I detect if a Firebase Storage file exists?如何检测 Firebase 存储文件是否存在?
【发布时间】:2016-11-06 04:43:18
【问题描述】:

我正在FIRStorageReference 上编写一个 Swift 扩展来检测文件是否存在。我打电话给metadataWithCompletion()。如果没有设置完成块的可选NSError,我认为假设文件存在是安全的。

如果设置了 NSError,则说明出现问题或文件不存在。 storage documentation on handling errors in iOS 声明 FIRStorageErrorCodeObjectNotFound 是我应该检查的错误类型,但无法解决(可能 Swiftified 为更短的 .Name 样式常量?)我不确定我应该检查什么反对。

如果FIRStorageErrorCodeObjectNotFound 设置在某处,我想打电话给completion(nil, false)

这是我目前的代码。

extension FIRStorageReference {
    func exists(completion: (NSError?, Bool?) -> ()) {
        metadataWithCompletion() { metadata, error in
            if let error = error {
                print("Error: \(error.localizedDescription)")
                print("Error.code: \(error.code)")

                // This is where I'd expect to be checking something.

                completion(error, nil)
                return
            } else {
                completion(nil, true)
            }
        }
    }
}

非常感谢。

【问题讨论】:

  • 我们故意没有构建“对象存在检查”,因为我们认为在对象获取或元数据获取上检查FIRStorageErrorCodeObjectNotFound 的错误代码已经足够了。你能否给我更多解释为什么你想要这个功能而不是仅仅做对象/元数据获取并在找不到所需对象时处理错误?
  • 获取元数据是一种很好的方法,我现在不确定我是如何确定发生了哪个错误。在我的代码中,我将如何处理这个 NSError 对象,如果没有错误对象,假设文件存在是否安全?谢谢。

标签: ios swift firebase-storage


【解决方案1】:

您可以像这样检查错误代码:

// Check error code after completion
storageRef.metadataWithCompletion() { metadata, error in
  guard let storageError = error else { return }
  guard let errorCode = FIRStorageErrorCode(rawValue: storageError.code) else { return }
  switch errorCode {
    case .ObjectNotFound:
      // File doesn't exist

    case .Unauthorized:
      // User doesn't have permission to access file

    case .Cancelled:
      // User canceled the upload

    ...

    case .Unknown:
    // Unknown error occurred, inspect the server response
  }
}

【讨论】:

  • 如果它传递.ObjectNotFound,你知道它是否仍然算作“读取”或请求?
  • 没有。来自 GCS 文档 (cloud.google.com/storage/pricing#operations-pricing),“注意:通常,您无需为返回 307、4xx 或 5xx 响应的操作付费。例外情况是启用网站配置且 NotFoundPage 属性设置为该存储桶中的公共对象。”
  • 很好 - 至少谷歌得到了你的支持?谢谢你的回复
【解决方案2】:

这是我用来检查用户是否已经通过 hasChild("") 方法获得用户照片的简单代码,参考在这里:
https://firebase.google.com/docs/reference/ios/firebasedatabase/interface_f_i_r_data_snapshot.html

希望对你有帮助

let userID = FIRAuth.auth()?.currentUser?.uid

        self.databaseRef.child("users").child(userID!).observeEventType(.Value, withBlock: { (snapshot) in
            // Get user value
            dispatch_async(dispatch_get_main_queue()){
                let username = snapshot.value!["username"] as! String
                self.userNameLabel.text = username
                // check if user has photo
                if snapshot.hasChild("userPhoto"){
                    // set image locatin
                    let filePath = "\(userID!)/\("userPhoto")"
                    // Assuming a < 10MB file, though you can change that
                    self.storageRef.child(filePath).dataWithMaxSize(10*1024*1024, completion: { (data, error) in
                        let userPhoto = UIImage(data: data!)
                        self.userPhoto.image = userPhoto
                    })
                }

【讨论】:

  • 谢谢,但hasChild() 和您提到的文档均指的是 Firebase 的 Database。我正在尝试检测 Firebase 存储中是否存在文件。我认为这些是完全不同的。
  • 抱歉没有更具体,当您将文件存储到 FIRsotrage 时,它​​会生成一个 URL,我使用 FIRdatabase 存储这个 URL 作为参考,所以我可以检查这个 URL 是否存在我可以知道该文件也存在。
  • 谢谢,但这似乎是一种解决方法,而不是正确的方法。我希望有某种方法可以在metadataWithCompletion() 中以编程方式破译错误的原因,但如何做到这一点并不明显。
【解决方案3】:

斯威夫特 5

let storageRef = Storage.storage().reference().child("yourPath").child("\(someFile)") // eg. someVideoFile.mp4

print(storageRef.fullPath) // use this to print out the exact path that your checking to make sure there aren't any errors

storageRef.getMetadata() { (metadata: StorageMetadata?, error) in
        
    if let error = error {
        guard let errorCode = (error as NSError?)?.code else {
            print("problem with error")
            return
        }
        guard let err = StorageErrorCode(rawValue: errorCode) else {
            print("problem with error code")
            return
        }
        switch err {
           case .objectNotFound:
                print("File doesn't exist")
            case .unauthorized:
                print("User doesn't have permission to access file")
            case .cancelled:
                print("User cancelled the download")
            case .unknown:
                print("Unknown error occurred, inspect the server response")
            default:
                print("Another error occurred. This is a good place to retry the download")
        }
        return
    }
        
    // Metadata contains file metadata such as size, content-type.
    guard let metadata = metadata else {
        // an error occured while trying to retrieve metadata
        print("metadata error")
        return
    }
        
    if metadata.isFile {
        print("file must exist becaus metaData is a file")
    } else {
        print("file for metadata doesn't exist")
    }
        
    let size = metadata.size
    if size != 0 {
        print("file must exist because this data has a size of: ", size)
    } else {
        print("if file size is equal to zero there must be a problem"
    }
}

没有详细错误检查的较短版本:

let storageRef = Storage.storage().reference().child("yourPath").child("\(someFile)")
storageRef.getMetadata() { (metadata: StorageMetadata?, error) in
        
    if let error = error { return }
    
    guard let metadata = metadata else { return }
        
    if metadata.isFile {
        print("file must exist because metaData is a file")
    } else {
        print("file for metadata doesn't exist")
    }
        
    let size = metadata.size
    if size != 0 {
        print("file must exist because this data has a size of: ", size)
    } else {
        print("if file size is equal to zero there must be a problem"
    }
}

【讨论】:

    猜你喜欢
    • 2021-02-26
    • 2016-10-11
    • 1970-01-01
    • 2022-01-24
    • 2013-04-12
    • 2022-08-21
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    相关资源
    最近更新 更多