2016-02-09 31 views
0

我正在用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); 
     }]; 

基本上發出多個更新相同請求中的相同路徑,事先不存在,同時避免覆蓋問題

回答

2

你的第一個例子翻譯成指令來更新:

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

第二個例子翻譯爲:

"users/posts/postid1" = postDescription 

作爲一個計算機程序,將火力地堡服務器採用的指令相當字面解釋你給它。它會執行每條更新指令,並將路徑(=之前的部分)中的數據替換爲值(=之後的部分)。

知道了,你可以看到在第二個例子中它會寫postDescriptionusers/posts/postid1。這將替換該帖子的現有描述,但這可能是您想到的。

第二個示例在users/posts處寫{ "postid1": postDescription }。這取代了該位置現有的價值,所以你基本上用新的/更新的所有現有的職位替換。這可能不是你想到的。

更新

如果您要創建一個新的對象和扇出關鍵到多個位置,您可以利用的事實,childByAutoId是一個純客戶端操作:

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

如果我想在同一個調用中創建兩個新帖子或「路徑」,同時仍然使用'childByAutoId',那麼最好的方法是什麼?試圖儘可能高效地編寫這些更新以吸引最小的移動數據和資源 – Erik

+0

'childByAutoId'是客戶端操作,因此您可以從中獲取密鑰。 。我會寫一個快速片段並將其添加到我的答案中。 –

+0

我看,不管位置如何,獲取'childByAutoId'的算法是否保持不變?我可以這樣做'讓newRef = ref。childByAutoId()''而'ref'是Firebase的根目錄,並將該密鑰用於不同的位置?那樣,如果出於某種原因需要,您可以「模擬」一個新的Firebase參考並使用它獲取新的唯一密鑰? – Erik

相關問題