2016-03-01 71 views
2

考慮跨多個地點原子寫入下面的代碼在火力點:火力地堡,多位置更新

var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com"); 

var newPostRef = ref.child("posts").push(); 
var newPostKey = newPostRef.key(); 

var updatedUserData = {}; 
updatedUserData["users/"+authData.uid+"/posts/" + newPostKey] = true; 
updatedUserData["posts/" + newPostKey] = { 
    title: "New Post", 
    content: "Here is my new post!" 
}; 

ref.update(updatedUserData, function(error) { 
    if (error) { 
    console.log("Error updating data:", error); 
    } 
}); 

這種方法可以用來更新在不同地點的職位,但如何在執行原子更新服務器端? (通過規則)。

如何確保用戶無法更新位置/posts/(通過其直接引用)而不填充users/UID/posts/,反之亦然?

回答

3

有很多可能的這樣的「業務規則」,所以我會選擇一個並實現它。假設任何用戶引用的帖子都必須存在。因此,如果/posts/mypostid存在,則只能寫入/users/myuid/posts/mypostid。我還會自己實現對帖子的基本驗證。

{ 
    "posts": { 
    "$postid": { 
     ".validate": "hasChildren(['title', 'content'])", 
     "title": { 
     ".validate": "newData.isString()" 
     }, 
     "content": { 
     ".validate": "newData.isString()" 
     }, 
     "$other": { 
     ".validate": false 
     } 
    } 
    }, 
    "users": { 
    "$uid": { 
     "posts": { 
     "$postid": { 
      ".validate": "newData.parent().parent().parent().parent().child('posts').child($postid).exists() 
     } 
     } 
    } 
    } 
} 

這裏最大的訣竅是newData.parent().parent()...位,這確保了我們得到的新數據的職位。

你有這樣一種習慣:問我「如何確保ABC方法用於更新數據?」,這種方法很少是正確思考問題的方法。在上面的規則中,我將重點放在驗證數據的結構上,而不關心哪些API調用可能會導致這些數據。

+0

謝謝弗蘭克,我使用了類似的方法,但我使用newData.val()而不是'exists()'來使用自己,順便說一句,我只是添加了「更新源」部分爲了讓讀者清楚,我正在尋找一個服務器端解決方案,以保證正確的輸出,無論客戶端發生了什麼......但無論如何感謝您的答案。解決了我的問題:) –

+0

如果您已經有一種方法無效,**總是**發佈您的問題。它表明你已經嘗試了一些東西,另外它還允許我們將片段複製/粘貼到我們的答案中。 –

+0

引用這個問題,'newData.parent()...'可以在特定節點的''.validate''規則中多次使用嗎? – Andrea