2016-12-09 73 views
0

我想確保2個值總是一起寫入實時db。Firebase原子寫入

我有以下佈局:

- > register_username

- - > uid_lookup

- - - > 「some_username」: 「some_uid」

- - - > username_lookup

- - - >「some_uid」:「some_username」

這些規則(很抱歉的格式):

// uid -> username && username -> uid 
"register_username": { 

    ".write":     "auth !== null", 
    ".validate":   "newData.hasChildren(['uid_lookup', 'username_lookup'])", 

    // username -> uid 
    "uid_lookup": { 

    "$username": { 
     ".validate": "newData.val() === auth.uid && !data.exists()" 
    } 

    }, 

    // uid -> username 
    "username_lookup": { 

    ".write":  "!data.exists()", 

    "$uid": { 
     ".validate": "auth.uid === $uid && newData.val().matches(/^[a-zA-Z0-9-_]{4,20}$/) && newData.parent().parent().child('uid_lookup/' + newData.val()).exists()" 
    } 

    }, 

    // don't allow any other children 
    "$other":    {".validate": false} 

} 

當我寫

{ 
    "uid_lookup": { 
    "username": "123" 
    }, 
    "username_lookup": { 
    "123":"username" 
    } 
} 

/register_username/它工作正常。

但是,爲什麼我能寫信給/register_username/uid_lookup/而沒有出現錯誤?

+0

我只是寫一個答案,但現在認識到,你可能會問你的唯一驗證規則。 : -/ –

回答

1

Firebase數據庫安全規則在寫入操作之前和之後驗證數據庫的狀態。他們不驗證三角洲。

所以你不應該試圖捕獲非法寫入。相反,你應該寫你的規則,只允許合法的數據結構。

對於/register_username/uid_lookup下的數據,您指定的全部內容是用戶只能編寫自己的uid。你可能想補充一點,確保他們只能寫一個UID以及一個映射的用戶名的條款:

"$username": { 
    ".validate": "newData.val() === auth.uid && !data.exists() && 
      newData.parent().parent().child('username_lookup').child(auth.uid).exists()" 
} 
+0

最後我必須使用:'「.validate」:「!data.exists()&& newData.val()=== auth.uid && newData.parent()。parent()。child ('username_lookup /'+ auth.uid).exists()「' 謝謝! – stulleman

+1

對,我並不確定你想要的支票。我更新了我的答案。 –

0

Permission cascades down in Firebase:一旦您授予樹中特定級別的用戶權限,您便無法在較低級別取走該權限。

你的規則開始限定用於/register_username作爲寫入規則:

".write": "auth !== null", 

這意味着,任何認證的用戶可以/register_username下寫入的所有數據(包括該節點本身)。