如何正确查询firestore数据库?
Posted
技术标签:
【中文标题】如何正确查询firestore数据库?【英文标题】:How to query a firestore database correctly? 【发布时间】:2021-06-26 17:12:35 【问题描述】:我编写了这个函数,它接收用户名和密码字符串。然后它会查询 firestore 数据库中的用户集合,以查看是否使用了该用户名。如果查询返回任何文档,它会返回并离开闭包。如果它没有找到文档,它会创建具有指定数据的用户。该函数正确写入数据库,但查询逻辑不起作用,因此多个用户具有相同的用户名。
这里是与函数相关的相关代码:
func createAccountWith(_ username: String, _ password: String)
let userPath = "users"
let store = Firestore.firestore()
let userDB = store.collection(userPath)
//Query the DB for the given username. If we find that username, then throw an error
userDB.whereField("username", isEqualTo: username).getDocuments() (querySnapshot, err) in
if let error = err
print("Error querying DB: \(error)")
return
for document in querySnapshot!.documents
if document.exists
return
//set data if no document exists
userDB.document("\(UUID().uuidString)").setData(
[
"username":username,
"password":password
]
)
【问题讨论】:
WWDC async await video 非常擅长解释“旧”方式、新方式以及如何使闭包与新方式协同工作。 【参考方案1】:在异步代码中,认为出现在另一行之前的代码行执行是错误的。在 OP 的情况下...
func createAccountWith(_ username: String, _ password: String)
let userPath = "users"
let store = Firestore.firestore()
let userDB = store.collection(userPath)
// *** THIS RUNS FIRST
//Query the DB for the given username. If we find that username, then throw an error
userDB.whereField("username", isEqualTo: username).getDocuments() (querySnapshot, err) in
// *** THIS RUNS THIRD, A "LONG TIME" AFTER
if let error = err
print("Error querying DB: \(error)")
return
for document in querySnapshot!.documents
if document.exists
return
// *** THIS RUNS SECOND, RIGHT AWAY, BEFORE THE GET COMPLETES
//set data if no document exists
userDB.document("\(UUID().uuidString)").setData(
[
"username":username,
"password":password
]
)
所以要修复,在发现没有匹配的用户名之后,在闭包内创建用户...
func createAccountWith(_ username: String, _ password: String)
let userPath = "users"
let store = Firestore.firestore()
let userDB = store.collection(userPath)
//Query the DB for the given username. If we find that username, then throw an error
userDB.whereField("username", isEqualTo: username).getDocuments() (querySnapshot, err) in
if let error = err
print("Error querying DB: \(error)")
return
for document in querySnapshot!.documents
if document.exists
// these returns return from the block, not the containing function
return
// no matching user found
//set data if no document exists
userDB.document("\(UUID().uuidString)").setData(
[
"username":username,
"password":password
]
)
// code placed here runs before the getDocuments completion block
// so nothing here can depend on the result of the get
【讨论】:
有没有办法让某些代码行在执行之前等待其他东西完成? 另外,有没有什么好的资源可以推荐给我,可以帮助我理解如何异步设计代码?我理解这个概念(两段代码同时执行,但是数据库查询比简单的 if 语句需要更长的时间才能完成),但我想知道这个事实应该如何改变我的编程 @BruceJagid - 你的意思是,还有另一种方法吗? swift 中的常用方法是传递一个在异步任务之后运行的完成块。我们强制用户 create 在 get 之后运行的方式是将 create 放在 get 的完成块中。以上是关于如何正确查询firestore数据库?的主要内容,如果未能解决你的问题,请参考以下文章
Vue Firestore 查询。 Firestore更新数据时如何避免重复?