首页 > 解决方案 > 当 Firestore 集合已经存在时如何捕获错误?

问题描述

现在,当 Firebase Firestore 中已存在集合时,我的应用程序正在崩溃。我想在它发生时捕捉到这个错误,但我当前的实现没有捕捉到任何东西,因为该addSnapshotListener()方法不会引发任何错误。

当前代码

let db = Firestore.firestore()
        
        do {
            try db.collection(chatName).addSnapshotListener { (Query, Error) in
                if Error != nil || Query?.documents != nil {
                    let alert = UIAlertController(title: "Chat Name Already Exists", message: "This chat name already exists, try again with a different name", preferredStyle: .alert)
                    alert.addAction(UIAlertAction(title: "Okay", style: .default, handler: { (UIAlertAction) in
                        alert.dismiss(animated: true, completion: nil)}))
                    AllChatsViewController().present(alert, animated: true)
                    completion()
                }
                else {
                    self.addChatToProfile(withName: chatName) {
                        completion()
                    }
                }
            }
        }
        catch {
            let alert = UIAlertController(title: "Chat Name Already Exists", message: "This chat name already exists, try again with a different name", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Okay", style: .default, handler: { (UIAlertAction) in
                alert.dismiss(animated: true, completion: nil)}))
            AllChatsViewController().present(alert, animated: true)
            completion()
        }

应用程序崩溃后的错误

线程 1:“无效的集合引用。集合引用必须有奇数个段,但有 0”

如何捕获此错误,以便显示带有错误的 UIAlertController?

标签: swiftfirebasegoogle-cloud-firestoretry-catch

解决方案


我会使用不同的方法。

要测试集合是否存在,请按名称读取该集合并通过 snapshot.count 确定是否有任何文档等于 0

这里的问题是集合可能包含大量数据,没有理由将所有数据读入或附加侦听器,因此我们需要使用该集合中的已知字段来限制结果。

我建议一个带有闭包的函数,如果集合存在则返回 true,如果不存在则返回 false,然后根据该结果采取行动。

您将需要要测试的集合的名称,然后是该集合中要查询的已知字段的名称以限制结果。

字段名称很重要,因为如果集合有 1M 文档,您不想全部阅读它们 - 您只想阅读一个,并且 .orderBy 有限制就可以做到这一点。

所以这是一个调用函数

func checkCollection() {
    self.doesCollectionExist(collectionName: "test_collection", fieldName: "msg", completion: { isEmpty in
        if isEmpty == true {
            print("collection does not exist")
        } else {
            print("collection found!")
        }
    })
}

然后该函数通过读取一个文档来检查集合是否存在,如果不存在则返回 false,如果存在则返回 true。

func doesCollectionExist(collectionName: String, fieldName: String, completion: @escaping ( (Bool) -> Void ) ) {
    let ref = self.db.collection(collectionName)
    let query = ref.order(by: fieldName).limit(toLast: 1)
    query.getDocuments(completion: { snapshot, error in
        if let err = error {
            print(err.localizedDescription)
            return
        }
        
        if snapshot!.count == 0 {
            completion(true)
        } else {
            completion(false)
        }
    })
}

推荐阅读