用于更新特定字段的Firebase扇出数据会删除其他兄弟字段

时间:2016-07-20 21:19:40

标签: ios json swift firebase firebase-realtime-database

每个用户都有一个会话节点,每次新会话都有新消息我需要为对话中涉及的两个用户更新两个会话节点,我只想在这里更新“lastMessage”和“tinestamp”字段是我的尝试:

let fanoutObject = [userPath      : dataToUpdate,
                    otherUserPath : dataToUpdate]

K.FirebaseRef.root.updateChildValues(fanoutObject)

每个用户的路径是:

"/users/{userID}/conversations/{conversationID}"

和dataToUpdate:

let dataToUpdate:[String:AnyObject] = ["timestamp"  : message.timestamp,
                                       "lastMessage": message.textBody]

结果:

每个用户的节点对话都已更新会话节点中的其他字段已被删除!

每个用户的会话节点是:

  "conversations" : {
    "{conversationID}" : {
      "lastMessage" : "your name ?",
      "seen" : true,
      "timestamp" : 1467849600000,
      "with" : {
        "country" : "US",
        "firstName" : "John",
        "profileImage" : "https://..."
      }
    }
  }

请注意,节点会话位于节点用户内,该节点是根节点用户 内的元素

并在更新之后:

  "conversations" : {
    "{conversationID}" : {
      "lastMessage" : "your name ?",
      "timestamp" : 1467849600000,
    }
  }

但是我希望更新这两个值并保留其他值?

根据文档我的代码应该有效:

  

updateChildValues更新已定义路径的某些键   替换所有数据。

2 个答案:

答案 0 :(得分:7)

解析代码有点困难,但很可能是updateChildValues()的行为让你感到困惑。

当您致电updateChildValues()时,Firebase服务器将遍历您传入的对象。对于其中的每个路径,它将使用您传入的值替换该路径中的整个值。 / p>

因此,如果您当前的JSON是:

{
  "Users": {
    "uidForUser1": {
      "name": "iOSGeek",
      "id": 2305342
    },
    "uidForUser2": {
      "name": "Frank van Puffelen",
      "id": 209103
    }
}

更新是(采用JSON格式,Firebase数据库的通用语言):

{
  "users/uidForUser2/name": "puf",
  "users/uidForUser1/name": "My actual name"
}

您的结果JSON将是:

{
  "Users": {
    "uidForUser1": {
      "name": "My actual name",
      "id": 2305342
    },
    "uidForUser2": {
      "name": "puf",
      "id": 209103
    }
}

但是如果您发送以下更新:

{
  "users/uidForUser1": {
    "name": "My actual name"
  },
  "users/uidForUser2": {
    "name": "puf"
  }
}

生成的JSON将是:

{
  "Users": {
    "uidForUser1": {
      "name": "My actual name"
    },
    "uidForUser2": {
      "name": "puf"
    }
}

<强>更新

更新同一对象中的两个字段,但不修改其他字段:

{
  "path/to/object/field1": "new value",
  "path/to/object/field2": "new value2"
}

答案 1 :(得分:2)

或者,您可以通过提供完整路径替换旧值来更新lastMessagetimeStamp数据:

let lastMessagePath = "/users/{userID}/conversations/{conversationID}/lastMessage"
let lastTimeStampPath = "/users/{userID}/conversations/{conversationID}/timestamp"

K.FirebaseRef.child(lastMessagePath).setValue(message.timestamp)
K.FirebaseRef.child(lastTimeStampPath).setValue(message.textBody)