如何正确查询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数据库?的主要内容,如果未能解决你的问题,请参考以下文章

如何在结构中正确显示来自 Firestore 的数据?

Vue Firestore 查询。 Firestore更新数据时如何避免重复?

如何使用 Firestore 运行地理“附近”查询?

如何在 Flutter 中从 Firestore 订购数据,orderBy 订购不正确

Firestore - 在本地合并两个查询

如何在 Cloud Firestore 中使用文档 ID 执行集合组查询