从 Firebase 仅检索当前用户的子值

Posted

技术标签:

【中文标题】从 Firebase 仅检索当前用户的子值【英文标题】:Retrieving only current user's child values from Firebase 【发布时间】:2017-04-07 13:43:41 【问题描述】:

编辑,底部更新,还是有问题


我的用户像这样存储在 Firebase 中 - 每个用户的值都存储在他们的 uid (FIRAuth.auth()?.currentUser?.uid) 下:

"users" : 
    "tzfHgGKWLEPzPU9GvkO4XE1QKy53" : 
      "gender" : "male",
      "handle" : "TestHandle2",
      "name" : "Timothy",
      "profilePicture" : "https://graph.facebook.com/*removed*/picture?type=large&return_ssl_resources=1"
    
  

现在要获取用户的信息(将其设置为我的 User 对象以在应用程序中使用),我有这个功能:

func getUserInfo() 
    let userRef: FIRDatabaseReference = FIRDatabase.database().reference().child("users")

    // How to get specific user (current user only)??
    userRef.observeSingleEvent(of: .value, with:  (snapshot) in
        let users = snapshot.value as! [String: Dictionary<String, String>]
        for (key, value) in users 
            guard let name = value["name"] else print("Error getting user name"); return
            guard let handle = value["handle"] else print("Error getting user handle"); return
            guard let gender = value["gender"] else print("Error getting user gender"); return
            guard let profilePicture = value["profilePicture"] else print("Error getting user profilePicture"); return
            print("\n\nName: \(name)\nHandle: \(handle)\nGender: \(gender)\nProfile Picture: \(profilePicture)\n\n")
        
    )

但是,这会返回数据库中所有用户的值 - 我只想获取当前用户的值。

我可以向这个函数添加/更改什么以确保它只检索当前用户的值,而不是所有用户的值?另外(如有必要,我可以提出一个单独的问题,但它似乎在这里相关),这种将每个用户的值存储为其 UID 的子项的结构是否是一种好方法?我注意到在其他示例中很多时候它们存储在childByAutoId 下。我不确定那会有什么优势。

感谢您的帮助!

编辑:

如果我将另一个子 (uid) 添加到引用的末尾,然后转换为 [String : AnyObject] 字典,我可以获得当前用户值,但解析它似乎是一个问题。

func getUserInfo() 

    guard let uid = FIRAuth.auth()?.currentUser?.uid else print("Error getting user UID"); return
    let userRef: FIRDatabaseReference = FIRDatabase.database().reference().child("users").child(uid)
    self.currentUser?.uid = uid

    userRef.observeSingleEvent(of: .value, with:  (snapshot) in

        if let usersDict = snapshot.value as? [String : AnyObject] 
            print(usersDict)
            for user in usersDict 
//                    guard let name = user.value(forKey: "name") else print("Error getting user name"); return
//                    guard let handle = user.value(forKey: "handle") else print("Error getting user handle"); return
//                    guard let gender = user.value(forKey: "gender") else print("Error getting user gender"); return
//                    guard let profilePicture = user.value(forKey: "profilePicture") else print("Error getting user profilePicture"); return
//                    print("\n\nName: \(name)\nHandle: \(handle)\nGender: \(gender)\nProfile Picture: \(profilePicture)\n\n")
            
        
    )

user.value(forKey) 的每一行都出现错误,指出“无法调用非函数类型 AnyObject 的值”。

如果我在循环内print(user.value),我会完美地恢复所有当前用户的值。我只是不能单独指定它们。

【问题讨论】:

【参考方案1】:

您需要向您的 userRef 添加另一个孩子

guard let uid = FIRAuth.auth()?.currentUser?.uid else 
        return
    

let userRef: FIRDatabaseReference = FIRDatabase.database().reference().child("users").child(uid)

【讨论】:

我已经尝试过了,但它导致了崩溃 - 不知道为什么,崩溃将我带到内存线程 (?) 屏幕。【参考方案2】:

先获取当前用户的UID,

let currentUid = FIRAuth.auth()?.currentUser?.uid 

然后替换这个数据库引用,

let userRef: FIRDatabaseReference = FIRDatabase.database().reference().child("users")

有了这个,

let userRef: FIRDatabaseReference = FIRDatabase.database().reference().child("users").child(currentUid)

:-)

【讨论】:

【参考方案3】:

这比你想象的要容易:-)

    let userRef: FIRDatabaseReference = FIRDatabase.database().reference().child("users").child(FIRAuth.auth()?.currentUser?.uid)

【讨论】:

嗯,这就是我试图用这个函数设置用户的值,包括他们的 UID。他们注册了该应用程序,并且他们的值存储在 Firebase 中。然后当他们进入应用程序时,调用这个函数来设置他们的用户对象与他们的信息。 看到您的编辑 - 这与所有 3 个答案推荐的方法相同,但会导致崩溃。 您确定用户已登录,并且您的 uid 值有效吗?如果子键为空,您将崩溃... 是的,如果我在 func 中说 guard let uid = FIRAuth.auth()?.currentUser?.uid else print("Error getting user UID"); return,然后是 print("\nUID: \(uid)\n"),它会打印我的 UID。【参考方案4】:

这是我加载用户信息的方式,

首先,我创建了一个名为 User 的 NSObject 类...

 import UIKit

class User: NSObject 

// Add Whatever Child values of the user you have here
var email: String?
var nickname: String?


然后我打电话给

func GetUserInfo() 

guard let uid = FIRAuth.auth()?.currentUser?.uid else 
        return
    

FIRDatabase.database().reference().child("users").child(uid)
.observeSingleEvent(of: .value, with:  (snapshot) in

            if let dictionary = snapshot.value as? [String: AnyObject] 

                let user = User()
                user.setValuesForKeys(dictionary)
                print(user.nickname!)

    , withCancel: nil)

不知道有没有帮助..

【讨论】:

我认为这通常是我正在尝试的,除了您不使用 for 循环,而是将快照转换为 [String: AnyObject]。如果我尝试为 uid 添加一个孩子,它会在到达 observeSingleEvent 行时立即崩溃。

以上是关于从 Firebase 仅检索当前用户的子值的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift 更新 Firebase 中的子值

当有唯一键 Kotlin 时如何从 Firebase 检索孩子

如何为具有特定子子值的子项检索 Firebase DatabaseReference?

我们如何在 Android Java 的 RecyclerView 中检索 uid 用户名和 uid 用户子值?

付款时的子值计数器 Firebase Android

如何读取 Firebase 子值?