(Swift) 如果我的节点是自定义索引的,如何只查询当前用户的实时数据的快照?

Posted

技术标签:

【中文标题】(Swift) 如果我的节点是自定义索引的,如何只查询当前用户的实时数据的快照?【英文标题】:(Swift) How Do I Query for Snapshot of Only the Current User's Real-Time Data if my Nodes are Custom Indexed? 【发布时间】:2018-04-21 01:08:41 【问题描述】:

抱歉,如果标题有点罗嗦:P 我正在使用 Swift 和 Firebase。

我在 Firebase 上设置了一条规则,以在“用户名”上为我的用户数据库编制索引,但是当我在代码中查询当前用户数据的快照时,它总是返回 nil...我猜是因为我只能通过 uid 纯粹识别当前用户??

这是我的示例 JSON 树:

正如您在上面看到的,在 Firebase 中,我根据用户在我的应用中创建的“用户名”为用户的数据编制了索引。 但是,当我想检索用户其他子节点的值时,我什至无法访问用户的数据树,因为就应用程序启动时而言,它不知道当前用户的“用户名” “……它只知道无限期的当前用户的uid。

我想做的事:

我想使用let user : String = (Auth.auth().currentUser?.uid)! 并在我的数据库中搜索与user 匹配的子节点值,然后我想获取该用户数据的快照...从标题“User1”开始>" 并包括它的所有子项。

请帮助我执行此操作的正确过程,我迷路了:P 谢谢!

【问题讨论】:

这个问题有点不清楚:uid 是 firebase 中每个用户的唯一标识符。当用户登录时,从 Auth 变量中获取他们的 uid。从那里您可以通过您创建的节点/users/uid_x 访问他们的用户节点。除此之外你还需要什么?您甚至不需要查询 - 只需通过 root_ref/users/uid_x 直接访问节点 @Jay 嗯,我不知道那个 'root_ref' 选项......我对 Swift/Firebase 还很陌生,并且(通过研究)的印象是为了检索数据它必须通过快照。在这种情况下,深入多个节点是行不通的,因为我必须通过用户名(在应用程序启动时未知)来定义用户的特定节点。但我会进一步研究您的建议,谢谢! 没有。我使用 root_ref 作为对 your firebase 的引用的占位符,即 your_firebase_reference/users/uid_x。您确实在快照中检索数据,并且有多种方法可以获取其中一种;观察、观察单事件和带有观察的查询。通常你定义一个用户节点来存储额外的用户数据; root_ref/users/uid_0 和 root_ref/users/uid_1 等,然后在他们登录后访问该用户,root_ref.child("users").child(some_uid).observeSingleEvent(of: .value将检索该特定用户节点。 哦,好的,我现在关注了,谢谢 :) 这种方法(对我而言)的唯一问题是我是通过用户的用户名而不是他们的 uid 来索引我的 Firebase 数据。因此,当我获取快照并尝试深入了解用户数据时,我首先定义“用户”节点......很好......但我数据库中的下一个节点是每个用户的用户名(我无法在应用程序启动)。用户的 uid 被列为该用户名节点内的子项,因此它是“隐藏”的。我想出了一个可行的替代方案,但我最终可能不得不解决一些稳定性问题......上面已回答。感谢您的帮助! 使用索引的原因是为了加快某些节点上的查询。如果您不按用户名经常进行查询,那么您就不需要对其进行索引。即,如果您的用户存储在我提到的模式中,则在他们进行身份验证后无需查询即可获取用户信息,因为您将通过他们的 uid 读取它(observeSingle)。 【参考方案1】:

这就是我最终要做的。我并没有声称它是最好的方法,但它有效并且清楚地显示了如何从 Firebase 中的键中检索子值:

下面的所有代码都在一个常规的自定义函数中(未显示)。

    if Auth.auth().currentUser != nil  //Makes sure that there is a user currently registered/logged in

    let ref = Database.database().reference() //Gets a reference to my database

    //Dives into the 'Users' node, then into the user's specific data node based on their username (gathered from device's 'User Defaults')
    ref.child("Users").child(username).observeSingleEvent(of: .value, with:  (snapshot) in

        let value = snapshot.value as? NSDictionary //Gets a snapshot of all the data specific to the current user
        let usersEmail = value?.value(forKeyPath: "Email") //Gets the value of the specified key in the snapshot

        print(usersEmail!)

        )
    

打印“a@b.com”。由于我通过每个用户的“用户名”作为包含数据子节点的主节点(而不是用户的 uid 作为主节点)来索引我的 Firebase 数据库,因此我需要将用户的用户名保存为他们设备的用户默认值中的字符串,以便在通过“用户名”特定节点识别当前用户的数据时可以调用该值。

请注意,这仅在您的应用支持在用户创建用户名时测试唯一用户名时才有效。

【讨论】:

嗯。此答案中的代码与您问题中的 Firebase 结构不匹配,问题询问 您如何查询 但这不是查询。此处的代码显示了如何观察单个 Firebase 节点,该节点也显示在 Read Data Once 部分的Firebase Guide 中。在您的 Firebase 结构中,用户名是 User1 节点的 子节点。只是要求将来的读者澄清一下。 是的,抱歉,这肯定会造成混淆。您指出的“用户名”... ref.child("Users").child(username)... 实际上是一个变量,它保存从用户默认值中检索到的用户用户名值。它有一个小的“u”,而不是带有一个大“U”的 Firebase 子节点“用户名”。获取该值的函数未包含在上述代码中,但为了清楚起见,我今晚可以添加它。此外,原始问题询问如果我无法定义它全部隐藏在内部的节点,如何查询用户数据的快照,但在这种情况下,用户默认值是答案。 它不是隐藏的——你可以随时查询子节点,不管它们的键是什么。在这种情况下,您可以轻松地在 /Users 节点中查询包含用户 EmailUser IDUsername 的任何子节点. 当试图获取所有当前用户的数据(只有当前用户,而不是其他用户的数据)时,我认为我遇到的问题是当我试图深入我的实时数据库,我必须从这样的结构中获取快照:“/A/B/C/abcd...”,其中每个大字母是子节点,小字母是子节点。如果我只想获取“abcd”的快照,我需要将“C”定义为路径,但如果它是用户名,则在应用启动时不知道,所以我从哪里检索它它已保存在用户默认值中。我愿意接受其他建议:) 如果我理解正确,那不是它的工作原理。如果您直接访问孩子,则只需要路径“C”。即,给定路径 /users/uid_0/user_name: "c.sagen" 并想要获取 uid_0 用户名,可以通过观察 /users/uid_0/user_name: 的路径并读取 snapshot.value 来访问它。但是,如果您在 /users/ 节点上执行 查询,您将查询 user_name = 'c.sagen' 这将返回整个 uid_0 节点(或具有该用户名的任何其他节点)。这是使用 uid 作为用户节点的密钥的另一个很好的理由,因为它总是从 auth.uid 获得的。

以上是关于(Swift) 如果我的节点是自定义索引的,如何只查询当前用户的实时数据的快照?的主要内容,如果未能解决你的问题,请参考以下文章

「Mysql索引原理(六)」聚簇索引

如何在 Swift 中检查我的数组索引是不是超出范围

如何在swift 3中找到数组包含字典的数组索引?

如何访问 SpriteKit 场景编辑器参考节点上自定义类中包含的 Swift 中的变量?

touchesBegan Swift 2 自定义 SpriteKit 节点

什么是自适应哈希索引