Firebase getDocument(querySnapshot)无法正常工作 [英] Firebase getDocument (querySnapshot) is not working

查看:54
本文介绍了Firebase getDocument(querySnapshot)无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正面临着Firebase快照的问题.我的Xcode项目成功连接了我的Fierbase帐户.我能够更改Firestore云中的数据.但是我看不懂.这是我的功能:

I'm facing an issus with the Firebase Snapshot. I conntected my Fierbase account succesfully with my Xcode project. I am capable to change data in my Firestore cloud. But I can't read it. Here is my function:


class UserService{
static func CheckIfMoreThanOneUserIsLoggedIn() -> Bool{
    var BoolenToReturn:Bool?
    let AuthUser = Auth.auth().currentUser
    let userId = AuthUser!.uid
    let localDeviceString = Constants.UserDefaultsStorage.string(forKey: userId)
    // LocalDeviceString is generated (20 random letters) when the user is logged in succesfully.
    //This DeviceString would be stored on one hand in the cloud on the other hand on the device.
    //When the user open the Application it checks if the localDeviceString of the cloud is the same as the String stored on the device.
    //I’m able to denie the user access through multiple devices simultaneously (-> Any imporvent is desired)
    let newUserReference = Firestore.firestore().collection("users").document(userId)
    newUserReference.getDocument {
        (querySnapshot, err) in // Code never runs the closure
        guard err != nil else {
            return
        }
        for document in querySnapshot!.data()! {
            if document.key == "RandomString" {
                let docValue:String = document.value as! String
                if docValue == localDeviceString{
                    BoolenToReturn = true
                }
                else{
                    BoolenToReturn = false
                }
            }
        }
    }

    return BoolenToReturn  ?? false
}
}

修改

基于@Frank van Puffelen的链接,我能够制定自己的解决方案.但是该程序并不像我想要的那样专业,因为现在它是在 LaunchViewController 中定义的函数.另外,我在 newUserReference.getDocument 的闭包中将segue调用到 HomeViewController .我不希望实现的功能:UserService类中定义的一个函数,如果允许用户使用该应用程序,则该函数将返回布尔值.

Based on @Frank van Puffelen's links I was able to make my own solution. But the program isn't as professional as I want because now it is a function defined in the LaunchViewController. In addition I'm calling the segue to the HomeViewController in the closure of newUserReference.getDocument . What I wan't to achieve: A function that is defined in the UserService Class which returns a bool if the user is allowed to use the app.

推荐答案

我认为您可能想研究完成处理程序.想法是调用异步函数,然后在该函数完成后执行任务.以下代码几乎可以直接用作您问题的解决方案.

I think you may want to investigate a completion handler. The idea is to call an asynchronous function and then perform a task when that function has completed. The below code can almost be directly applied as a solution to your question.

因此,您可以从以下示例开始.假设我们有一个用户存储在用户集合中的应用

So here's an example you can start with. Suppose we have an app with users stored in a users collection

users
   uid_0
      name: "Steve"
   uid_1
      name: "Danno"
   uid_2
      name: "Junior"
   uid_3
      name: "Tani"

,并且有新用户想要注册,但该应用不允许重复的名称.因此,我们需要查询用户集合以确定该名称是否已被使用.这是调用查询功能的代码.

and a new user wants to sign up, but the app doesn't allow for duplicate names. So we need to query our users collection to determine if the name is already in use. Here's the code that calls the query function.

self.doesUserNameExist(userName: "Steve" ) { doesExist in
    if doesExist == true {
        print("yep, it exists")
    } else {
        print("Nope - it's not there")
    }
}

print("this code will execute before the above code")

可以打印,它存在

,这是执行查询的实际功能.请注意,我们如何使用完成处理程序,即在完成操作后@@转义闭包.

and here's the actual function that performs the query. Note how we're using an completion handler thats @escaping the closure when it's done.

//determine if a user name exists in Firestore, return true if it does, false if not
func doesUserNameExist(userName: String, completion: @escaping( (Bool) -> Void) ) {
    let usersCollection = self.db.collection("users")
    usersCollection.whereField("name", isEqualTo: userName).getDocuments(completion: { querySnapshot, error in
        if let err = error {
            print(err.localizedDescription)
            return
        }
        
        guard let docs = querySnapshot?.documents else { return }
        
        if docs.count > 0 {
            completion(true)
        } else {
            completion(false)
        }
    })
}

这是从异步函数返回"数据的典型方法,因为它允许函数执行,使数据有效,然后以异步方式将该数据传递回调用函数.

This is the typical way to 'return' data from an asynchronous function as it allows the function to execute, the data to be valid and then pass that data back to the calling function in an asynchronous way.

请注意,调用函数之后的任何代码都应这样

Note that any code following the calling function, like this

print("this code will execute before the above code")

将在函数闭包中的代码之前执行.

Will execute before the code in the function closure.

编辑

以上称呼为这样的称呼

self.doesUserNameExist(userName: "Jay", completion: { doesItExist in
    print(doesItExist)
})

这篇关于Firebase getDocument(querySnapshot)无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆