【问题标题】:How to use a node under a user's node to create a list?如何使用用户节点下的节点创建列表?
【发布时间】:2021-03-04 11:47:59
【问题描述】:

我正在尝试创建两个带有在两个之间切换的分段按钮的表。我目前有代码来切换两个表的可见性。我正在使用 firebase,并希望能够通过我放入他们的 json 树中的特定“标签”来区分用户。

例子:

Users:
     |
    4774893HUjd8
               |
              Name: John Doe
              Email: example@example.com
              Tag: Macro
     |
    38849HHIJDO877
               |
               Name: Jane Doe
               Email: example2@example.com
               Tag: Micro

我希望能够将它们保留在用户节点中。我不想创建宏和微用户节点,因为如果用户升级他们的帐户,我可以更新 firebase 中的标签。

这是我目前在项目中加载数据的方式:

func updateDataArray() {
    
    Database.database().reference().child("Users").observe(.childAdded, with: { (snapshot) in
        
        if let dictionary = snapshot.value as? [String: AnyObject] {
            
            let user = User()
            //self.setValuesForKeys(dictionary)
            user.Name = dictionary["Name"] as? String
            user.Email = dictionary["Email"] as? String
            user.ProfileImageUrl = dictionary["ProfileImageUrl"] as? String
            user.UID = dictionary["UID"] as? String
            user.UserCategory = dictionary["UserCategory"] as? String
            
            self.users.append(user)
            self.userName.append(user.Name!)
            self.filteredNames.append(user.Name!)
            
            print(dictionary)
            
            DispatchQueue.main.async {
            self.tableView.reloadData()
                }
            }
        }, withCancel: nil)
    }

我使用 swift 和 firebase 作为我的后端。我真的可以使用帮助,并希望尽快解决这个问题。

编辑:这是我的用户结构,它会很有帮助。

import UIKit

class User: NSObject {
    var Name: String?
    var Email: String?
    var ProfileImageUrl: String?
    var UID: String?
    var Tag: String?
}

我还添加了您建议的两个不同的数组。

我将表格计数和输入更改为各自的标签数组。

我很难更新子值并附加正确的数组。

func createDataArray() {
    
    Database.database().reference().child("Users").observe(.childAdded, with: { (snapshot) in
        
        if let dictionary = snapshot.value as? [String: AnyObject] {
            
            let user = User()
            //self.setValuesForKeys(dictionary)
            user.Name = dictionary["Name"] as? String
            user.Email = dictionary["Email"] as? String
            user.UID = dictionary["UID"] as? String
            user.Tag = dictionary["Tag"] as? String
            
            if user.Tag == "Macro" {
                            self.macroUsersArray.append(user)
            } else if user.Tag == "Micro" {
                            self.microUsersArray.append(user)
                        }
            
            self.users.append(user)
            self.userName.append(user.Name!)
            self.filteredNames.append(user.Name!)
            
            print(dictionary)
            print(self.macroUsersArray)
            
            DispatchQueue.main.async {
            self.tableView.reloadData()
                }
            }
        }, withCancel: nil)
    }

这是我试图用来删除更新的子节点“标签”并更新我的表的数组的代码,

func updateDataArray() {
    
    Database.database().reference().child("Users").observe(.childChanged, with: { (snapshot) in
        
        if let dictionary = snapshot.value as? [String: AnyObject] {
            
            let user = User()
            //self.setValuesForKeys(dictionary)
            user.Name = dictionary["Name"] as? String
            user.Email = dictionary["Email"] as? String
            user.UID = dictionary["UID"] as? String
            user.Tag = dictionary["Tag"] as? String
            
            if user.Tag == "Macro" {
                self.microUsersArray.removeAll()
            } else if user.Tag == "Micro" {
                self.macroUsersArray.removeAll()
                        }
            
            self.users.append(user)
            self.userName.append(user.Name!)
            self.filteredNames.append(user.Name!)
            
            print(dictionary)
            print(self.macroUsersArray)
            
            DispatchQueue.main.async {
            self.tableView.reloadData()
                }
            }
        }, withCancel: nil)
    
    }

【问题讨论】:

  • 两件事;您可能应该使用用户 uid 作为用户节点中其节点的键,例如/users/uid_x。第二件事是,你在问什么,什么不起作用?问题提到创建一个列表,但在代码中没有任何迹象 - 一个列表......什么?其他用户?最喜欢的食物?哦,这个user.Name! 很危险,因为它是可选的as? String。而且你不需要在 firebase 闭包中使用这个 DispatchQueue.main.async,因为 UI 调用会在主线程上自动调用。
  • 嘿,杰。感谢您的评论。我希望能够将用户加载到 2 个不同的组中以显示在 2 个不同的表中。我想将它们全部加载到那里,然后通过每个用户节点下的标签来区分它们。在我的示例中,标签是宏和微。我想访问所有其他信息以及标签,因此标签不能位于所有其他信息之前。我还希望能够将标签从宏更新到微,反之亦然,而无需重新输入信息。这样我就可以用一点零钱把它们移到桌子上。
  • 我忘了说我编的那些数字是uid。

标签: arrays swift xcode firebase uitableview


【解决方案1】:

我不确定我是否理解这个问题,但它从 OP 想要在所有用户中读取并基于子节点的 cmets 中出现,将它们分成两个列表(微和宏)以用作 tableView 数据源。

从一个用户类开始保存用户信息

class UserClass {
    var uid = ""
    var name = ""
    var email = ""
    var tag = ""

    convenience init(withSnap: DataSnapshot) {
        self.init()
        self.uid = withSnap.key
        self.name = withSnap.childSnapshot(forPath: "Name").value as? String ?? "No Name"
        self.email = withSnap.childSnapshot(forPath: "Email").value as? String ?? "No Email"
        self.tag = withSnap.childSnapshot(forPath: "Tag").value as? String ?? "Micro"
    }
}

然后将两个数组用作 tableView 数据源。一个包含微型用户,另一个包含宏用户。这些通常是 tableViewDataSource 函数可以访问的类变量:

var macroUsersArray = [UserClass]()
var microUsersArray = [UserClass]()

然后是读取所有用户的 Firebase 代码,对其进行迭代,然后添加到适当的数组中

func readAllUsersAndAddToDatasource() {
    let usersRef = self.ref.child("Users")
    usersRef.observeSingleEvent(of: .value, with: { snapshot in
        let allUsersSnap = snapshot.children.allObjects as! [DataSnapshot]
        for childSnap in allUsersSnap {
            let user = UserClass(withSnapshot: childsnap)
            if user.Tag = "Macro" {
                self.macroUsersArray.append(user)
            } else {
                self.microUsersArray.append(user)
            }
        }
    })
}

编辑:

如果我们不使用 Firebase 事件(例如,如上所示通过 observeSingleEvent 读取用户),一个可能的工作流程

  1. 在宏数组中选择要从宏更改为微的用户
  2. 更改用户属性
  3. 从宏数组中删除用户(重新加载宏 tableView)
  4. 将用户添加到微阵列(重新加载微表视图
  5. 在 Firebase 中更新用户的属性

如果您使用事件,则模式不同

将 .changed 事件添加到用户节点以监视更改。

  1. 在宏数组中选择要从宏更改为微的用户
  2. 获取用户密钥 (uid) 并将更改写入 firebase,触发更改事件
  3. 在更改后的闭包中,从宏数组中删除用户(重新加载 tableView)
  4. 将用户添加到微阵列(重新加载 tableView)

【讨论】:

  • 嘿,杰。在你的帮助下,我非常接近解决这个问题。我编辑了我的问题,为您提供更多信息,并向您展示我目前所处的位置。再次感谢你的帮助。希望这对您来说是一个超级快速的解决方案,所以我可以在其他事情发生故障之前让您休息一下哈哈。
  • @NewCoder 请记住,从概念上讲,如果您有两个数组(一个用于微型用户,一个用于宏用户)并且您将用户从一个更改为另一个,您需要从一个数组中删除它们并将它们添加到另一个,然后刷新您的 tableView 以反映该更改。话虽如此,根据您使用 firebase 的方式,您可能希望观察 .childAdded、.childChanged 和 .childRemoved 的相关对象,因此如果您对 Firebase 本身进行更改,您的代码将自动知道该更改并可以更新各自的dataSource数组。
  • 太棒了。我提前道歉,但是当我在 firebase 中更改标签时,我将如何设置它,它只是在应用程序上更新?
  • @NewCoder 这将取决于您的用例。我的答案一次加载所有用户并将它们放入相应的数组中,而您的代码添加了一个观察者来观察未来的 childAdded 事件。我不知道这是否是你想做的。有两种选择; 1)根据我的回答加载用户,当发生变化时,将该数据写入 Firebase 并在数组中进行更改。 2) 将数据写入 Firebase 并让 firebase 观察者根据这些事件更新数组。更多活动信息Work with Lists
  • 我尝试将 observe.ChildAdded 更改为 observe.ChildChanged 并且表格现在没有加载。我想用你的第二个例子。我可以在 firebase 中更改用户标签,并让它在所有用户的应用程序上自动更改。
猜你喜欢
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
  • 2012-11-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-16
  • 1970-01-01
  • 2019-05-10
相关资源
最近更新 更多