首页 > 解决方案 > 如何正确查询firestore数据库?

问题描述

我编写了这个函数,它接受用户名和密码字符串。然后它会查询 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
            ]
        
        )
        
        
    }

标签: google-cloud-firestoreswiftui

解决方案


在异步代码中,认为出现在另一行之前的一行代码在它之前执行是错误的。在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
    }

推荐阅读