如何使用childByAutoId更新Firebase中的值?

时间:2022-01-31 20:21:01

When I create objects in Firebase, I use childByAutoId. How can I update these specific objects later? I'm having trouble obtaining the value of the key Firebase automatically updates. Snapshot.key just returns "users". Here's my JSON structure:

当我在Firebase中创建对象时,我使用childByAutoId。我如何在以后更新这些特定对象?我无法获得密钥Firebase自动更新的价值。 Snapshot.key只返回“用户”。这是我的JSON结构:

{
  "users" : {
    "-KQaU9lVcUYzIo52LgmN" : {
      "device" : "e456f740-023e-440a"
      "name: "Test"
    }
  },

How can I get the -KQaU9lVcUYzIo52LgmN key? I want to update the device child. Here's what I have so far. It currently creates a completely separate snapshot with a single child.

如何获得-KQaU9lVcUYzIo52LgmN键?我想更新设备子。这是我到目前为止所拥有的。它目前使用单个子项创建一个完全独立的快照。

self.rootRef.child("users").queryOrdered(byChild: "name").queryEqual(toValue: self.currentUser).observeSingleEvent(of: .value, with: { (snapshot) in
    let key = self.rootRef.child("users").childByAutoId().key
    let childValues = ["device": device]
    self.rootRef.child("users").child(key).updateChildValues(childValues)

Edit: device is a string set further up in the code. Not defined in this scope (to make it easier to read for this question).

编辑:设备是代码中进一步设置的字符串。未在此范围中定义(以便更容易阅读此问题)。

3 个解决方案

#1


5  

When you get Snapshot.key, it returns "users" because that is the overall key for your snapshot. Everything inside of "users" in your snapshot is considered the value.

当您获得Snapshot.key时,它将返回“users”,因为这是您的快照的整体关键。快照中“用户”内的所有内容都被视为值。

You need to iterate over the child layers to dig down to "device".

您需要遍历子图层以挖掘“设备”。

Try this:

rootRef.child("users").observeSingleEventOfType(.Value, withBlock: { (snapshot) in 
    if let result = snapshot.children.allObjects as? [FIRDataSnapshot] {
        for child in result {
            var userKey = child.key as! String
            if(userKey == userKeyYouWantToUpdateDeviceFor){
                rootRef.child("users").child(userKey).child("device").setValue(device)
            }
        }
    }
})

This code will do the following:

此代码将执行以下操作:

  1. Gets snapshot of your reference (the key for that would be 'users').
  2. 获取引用的快照(关键是'用户')。

  3. Gets all the children (your user keys) and assigns them as another snapshot to 'result'.
  4. 获取所有子项(您的用户键)并将它们作为另一个快照分配给“结果”。

  5. Checks each key one at a time until it finds the key you want (for example, if you look for user with the key "-KQaU9lVcUYzIo52LgmN", it will find it on the first iteration in your example code you posted).
  6. 每次检查每个密钥,直到找到所需的密钥(例如,如果您查找具有密钥“-KQaU9lVcUYzIo52LgmN”的用户,它将在您发布的示例代码的第一次迭代中找到它)。

  7. Once it finds that key, it sets the value for the device inside that key with the line rootRef.child("users").child(userKey).child("device").setValue(device).
  8. 一旦找到该密钥,它就会使用rootRef.child(“users”)行设置该密钥内设备的值.child(userKey).child(“device”)。setValue(device)。

Of course, you will need to store all your user keys when you make them. You can maybe use SharedPreferences on the device for this, but if it gets cleared for any reason then that data will just be sitting there. You could also store it on internal storage for your app, but SharedPreferences is what I would use.

当然,您需要在制作用户密钥时存储它们。您可以在设备上使用SharedPreferences,但如果它因任何原因被清除,那么该数据就会坐在那里。您也可以将其存储在应用程序的内部存储中,但我会使用SharedPreferences。

Hope this helps!

希望这可以帮助!

#2


1  

snapshot has a property key which is

快照有一个属性键

The key of the location that generated this FIRDataSnapshot.

生成此FIRDataSnapshot的位置的关键。

And as you can see you are getting one (snapshot) by calling observeSingleEvent(of: .value, with: { (snapshot)...

通过调用observeSingleEvent(of:。value,with:{(snapshot)...,你可以看到你得到一个(快照)...

so instead of let key = self.rootRef.child("users").childByAutoId().key

所以代替let key = self.rootRef.child(“users”)。childByAutoId()。key

try to call let key = snapshot.key

尝试调用let key = snapshot.key

childByAutoId().key always generates new unique key based on timestamp, that's why you are creating new child, not updating the one you want

childByAutoId()。key总是根据时间戳生成新的唯一键,这就是你创建新子的原因,而不是更新你想要的那个

Hope that works

希望有效

#3


0  

I adapted Ryan's answer to my own issue (kinda similar) and figured out a way to update your device ID directly without needed to know/store the AutoID key generated by Firebase :

我根据自己的问题(有点类似)调整了Ryan的答案,并想出了一种直接更新设备ID的方法,而无需知道/存储Firebase生成的AutoID密钥:

reference = Database.database().reference().child("users")

reference.observeSingleEvent(of: .value, with: { (snapshot) in
                            if let result = snapshot.children.allObjects as? [DataSnapshot] {
                                for child in result {
                                    if child.childSnapshot(forPath: "device").value as? String == self.yourDeviceIDVariable {
                                        print("### Device exists in Firebase at key = \(child.key)")
                                        let childKey = child.key
                                        self.reference.child(childKey).child("device").setValue(yourNewDeviceID)
                                    }
                                }
                            }
                        })

#1


5  

When you get Snapshot.key, it returns "users" because that is the overall key for your snapshot. Everything inside of "users" in your snapshot is considered the value.

当您获得Snapshot.key时,它将返回“users”,因为这是您的快照的整体关键。快照中“用户”内的所有内容都被视为值。

You need to iterate over the child layers to dig down to "device".

您需要遍历子图层以挖掘“设备”。

Try this:

rootRef.child("users").observeSingleEventOfType(.Value, withBlock: { (snapshot) in 
    if let result = snapshot.children.allObjects as? [FIRDataSnapshot] {
        for child in result {
            var userKey = child.key as! String
            if(userKey == userKeyYouWantToUpdateDeviceFor){
                rootRef.child("users").child(userKey).child("device").setValue(device)
            }
        }
    }
})

This code will do the following:

此代码将执行以下操作:

  1. Gets snapshot of your reference (the key for that would be 'users').
  2. 获取引用的快照(关键是'用户')。

  3. Gets all the children (your user keys) and assigns them as another snapshot to 'result'.
  4. 获取所有子项(您的用户键)并将它们作为另一个快照分配给“结果”。

  5. Checks each key one at a time until it finds the key you want (for example, if you look for user with the key "-KQaU9lVcUYzIo52LgmN", it will find it on the first iteration in your example code you posted).
  6. 每次检查每个密钥,直到找到所需的密钥(例如,如果您查找具有密钥“-KQaU9lVcUYzIo52LgmN”的用户,它将在您发布的示例代码的第一次迭代中找到它)。

  7. Once it finds that key, it sets the value for the device inside that key with the line rootRef.child("users").child(userKey).child("device").setValue(device).
  8. 一旦找到该密钥,它就会使用rootRef.child(“users”)行设置该密钥内设备的值.child(userKey).child(“device”)。setValue(device)。

Of course, you will need to store all your user keys when you make them. You can maybe use SharedPreferences on the device for this, but if it gets cleared for any reason then that data will just be sitting there. You could also store it on internal storage for your app, but SharedPreferences is what I would use.

当然,您需要在制作用户密钥时存储它们。您可以在设备上使用SharedPreferences,但如果它因任何原因被清除,那么该数据就会坐在那里。您也可以将其存储在应用程序的内部存储中,但我会使用SharedPreferences。

Hope this helps!

希望这可以帮助!

#2


1  

snapshot has a property key which is

快照有一个属性键

The key of the location that generated this FIRDataSnapshot.

生成此FIRDataSnapshot的位置的关键。

And as you can see you are getting one (snapshot) by calling observeSingleEvent(of: .value, with: { (snapshot)...

通过调用observeSingleEvent(of:。value,with:{(snapshot)...,你可以看到你得到一个(快照)...

so instead of let key = self.rootRef.child("users").childByAutoId().key

所以代替let key = self.rootRef.child(“users”)。childByAutoId()。key

try to call let key = snapshot.key

尝试调用let key = snapshot.key

childByAutoId().key always generates new unique key based on timestamp, that's why you are creating new child, not updating the one you want

childByAutoId()。key总是根据时间戳生成新的唯一键,这就是你创建新子的原因,而不是更新你想要的那个

Hope that works

希望有效

#3


0  

I adapted Ryan's answer to my own issue (kinda similar) and figured out a way to update your device ID directly without needed to know/store the AutoID key generated by Firebase :

我根据自己的问题(有点类似)调整了Ryan的答案,并想出了一种直接更新设备ID的方法,而无需知道/存储Firebase生成的AutoID密钥:

reference = Database.database().reference().child("users")

reference.observeSingleEvent(of: .value, with: { (snapshot) in
                            if let result = snapshot.children.allObjects as? [DataSnapshot] {
                                for child in result {
                                    if child.childSnapshot(forPath: "device").value as? String == self.yourDeviceIDVariable {
                                        print("### Device exists in Firebase at key = \(child.key)")
                                        let childKey = child.key
                                        self.reference.child(childKey).child("device").setValue(yourNewDeviceID)
                                    }
                                }
                            }
                        })