更新Firebase会删除现有数据

时间:2016-02-09 07:37:34

标签: ios objective-c firebase

我正在使用Firebase构建应用,最近我使用此代码来更新"帖子"的列表/字典。在用户词典中。看看:

Firebase *baseRef = [[Firebase alloc] initWithUrl:@"https://<MY-APP>.firebaseio.com"];

NSString *userPostsPath = [NSString stringWithFormat:@"users/%@/posts", userId];

NSDictionary *postRef = @{ postId : postDescription };

[baseRef updateChildValues:@{
                             userPostsPath : postRef
                             // here I'd have a similar update
                             }withCompletionBlock:^(NSError *error, Firebase *ref) {
                                 handler(error, ref);
                             }];

这适用于第一次更新,但第二次执行此操作时,将删除所有现有帖子。但是,将代码更改为:

Firebase *baseRef = [[Firebase alloc] initWithUrl:@"https://tonightdb.firebaseio.com"];

NSString *usersPostsPath = [NSString stringWithFormat:@"users/%@/posts/%@/", userId, postId];

[baseRef updateChildValues:@{
                             usersPostsPath : postDescription,
                             // similar update path
                             }withCompletionBlock:^(NSError *error, Firebase *ref) {
                                 handler(error, ref);
                             }];

正确更新Firebase。

这两者有什么区别?第一个怎么办?

修改

是否可以这样做:

Firebase *baseRef = [[Firebase alloc] initWithUrl:@"https://<MY-APP>.firebaseio.com"];
NSString *newKey = [baseRef childByAutoId];

然后使用该密钥执行如下所示的更新:

[baseRef updateChildValues:@{
                           [NSString stringWithFormat:@"/posts/%@/", newKey] : // something
                           [NSString stringWithFormat:@"/posts/%@/members/<something>", newKey] : // something
withCompletionBlock:^(NSError *error, Firebase *ref) {
            handler(error, ref, task);
        }];

基本上是在同一个请求中对同一路径发出多个更新,事先并不存在,同时避免覆盖问题

1 个答案:

答案 0 :(得分:2)

您的第一个示例转换为更新说明:

"users/posts" = { "postid1": postDescription }

第二个例子转换为:

"users/posts/postid1" = postDescription

作为一个计算机程序,Firebase服务器对您提供的指令进行了非常直接的解释。它接受每条更新指令,并将路径(=之前的部分)中的数据替换为值(=之后的部分)。

知道了,您可以看到在第二个示例中,它会在postDescription处写users/posts/postid1。这将替换该帖子的现有描述,但这可能是您的想法。

第二个示例在{ "postid1": postDescription }处写users/posts。这将取代该位置的现有值,因此您实际上将使用新的/更新的帖子替换所有现有帖子。这可能不是你的想法。

<强>更新

如果您正在创建一个新对象并将密钥扇出到多个位置,那么您可以利用childByAutoId是纯客户端操作的事实:

let newRef = ref.childByAutoId()
let newKey = newRef.key
ref.childByAppendingPath("child1").childByAppendingPath(newKey).setValue("one")
ref.childByAppendingPath("child2").childByAppendingPath(newKey).setValue("two")