swift - NSInternalInconsistencyException', reason: 'FIRESTORE INTERNAL ASSERTION FAILED
问题描述
I got an error
"Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'FIRESTORE INTERNAL ASSERTION FAILED: Invalid document reference. Document references must have an even number of segments, but documents has 1' terminating with uncaught exception of type NSException"
Here is my code and I don't known what wrong with my code ;-;
let docRef = db.collection("documents").document(self.txt_email.text!)
print(docRef.getDocument{ (document, error)
in print("DOC", document?.exists)
if(document?.exists == true){
print("EXISTS")
}else{
print("NOT EXISTS")
db.collection("documents").document(self.txt_email.text!).setData([:])
}
})
And here is my full Login code
let db = Firestore.firestore()
db.collection("Person").whereField("email", isEqualTo: email).getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
let docRef = db.collection("documents").document(self.txt_email.text!)
print(docRef.getDocument{ (document, error)
in print("DOC", document?.exists)
if(document?.exists == true){
print("EXISTS")
}else{
print("NOT EXISTS")
db.collection("documents").document(self.txt_email.text!).setData([:])
}
})
let document = querySnapshot!.documents.first
let account = Mapper<Account>().map(JSONObject: document!.data())!
ManageCacheObject.saveCurrentAccount(account)
self.txt_email.text = ""
self.txt_password.text = ""
let mainViewController:MainViewController?
mainViewController = UIStoryboard.mainViewController()
self.navigationController?.pushViewController(mainViewController!, animated: true)
hud.dismiss()
}
解决方案
代码存在一些问题,还有一个整体设计潜在问题。
这是第一个问题
self.txt_email.text!
如果 text 为 nil 会发生什么?然后你的代码爆炸了(根据你的问题)。这 !表示这是一个可选的,所以它可能是 nil。
最好通过使用 nil 合并运算符来设置默认值或完全避免调用它的 nil 来处理这个问题。
guard let email = self.txt_email.text else { return }
let docRef = db.collection("documents").document(email)
这是第二个问题。Firestore 是异步的,闭包之后的代码将在闭包中的代码之前执行。所以在这个firebase调用中
print( docRef.getDocument{ (document, error) in
闭包之后的行
let document = querySnapshot!.documents.first
将在闭包之前执行,在某些情况下可能会导致崩溃 - 取决于在闭包中操作的数据数据中/正在执行的操作。在这个用例中,这可能不是问题,但需要注意。
设计明智 - 电子邮件地址可以包含 documentId 中应避免的字符。
另外,如果电子邮件地址发生变化会怎样?您必须更改整个数据库中对该电子邮件的所有引用。
您的结构未包括在内,所以我不知道它是什么,但通常最好将 documentId 与文档包含的数据区分开来。例如
People //collection
person_id_0 //documentId is auto generated by Firestore
person_name //fields
email
person_id_1 //document
person_name //fields
email
documents //collection
document_0 //document
email //field
document_1
email
因此,一旦您拥有 person_id_0 的电子邮件,您就可以查询文档集合以查看它是否存在。如果电子邮件更改,您只需在一处更改。同样,这避免了由可能出现在电子邮件地址中的字符引起的问题。
推荐阅读
- ios - iOS IDFA AppsFlyer - 事件不会记录
- asp.net - 动态改变asp.net core的授权方式质询方案
- android - Pepper 机器人模拟器无法访问互联网
- spring - java.sql.SQLSyntaxErrorException:无法创建整数列
- bash - Shell: conditional appending or copying of CSVs with header
- python - 我应该使用评估生成器还是评估来评估我的 CNN 模型
- stata - 带有因子变量符号的 estpost
- python - 如何定义与三角函数相乘的常数
- flutter - 创建共享类 Flutter
- symfony - 在购物车中获取比例单位