2017-02-12 66 views
0

我想檢查用戶名是否已被使用。這個函數被調用時,當前用戶沒有「用戶名」的孩子:檢查唯一用戶名時拒絕Firebase權限

func createUsername() 
{ 
    let userID = FIRAuth.auth()?.currentUser?.uid 
    FIRDatabase.database().reference().updateChildValues([ 
     "users/\(userID!)/username": username.text!, 
     "usernames/\(username.text!)": userID! 
     ], withCompletionBlock: { (error, reference) in 
      if (error != nil) { 
       print("disallowed") 
       // Write was disallowed because username exists 
      } 
    }) 
} 

在結合這個規則:

{ 
    "rules": { 
    "users": { 
     "$uid": { 
     ".read": "$uid === auth.uid", 
     ".write": "$uid === auth.uid", 
     "username": { 
     ".read": true, 
      ".write": "!data.exists() && newData.exists()", 
      ".validate": "newData.isString()" 
     } 
     } 
    }, 
    "usernames": { 
     "$username": { 
     ".read": true, 
     ".write": "!data.exists() && newData.exists()", 
     ".validate": "newData.isString() && newData.val() == root.child('users/' + auth.uid + '/username').val()" 
     } 
    } 
    } 
} 

我得到了答案來自:https://groups.google.com/forum/#!topic/firebase-talk/dA1Lkykd-tk 我得到這個錯誤消息:

[Firebase/Database][I-RDB03812] updateChildValues: at/failed: permission_denied

我不知道爲什麼這不會工作。我也試過這個答案:Firebase android : make username unique但是這不適合我。規則有問題,但我不知道是什麼。

更新,在規則中變化不大,還是同樣的錯誤:

{ 
    "rules": { 
    "users": { 
     "$uid": { 
     ".read": "$uid === auth.uid", 
     ".write": "$uid === auth.uid", 
     "username": { 
     ".read": true, 
      ".write": "!data.exists() && newData.exists()", 
      ".validate": "newData.isString()" 
     } 
     } 
    }, 
    "usernames": { 
     "$username": { 
     ".read": true, 
     ".write": "!data.exists() && newData.exists()", 
     ".validate": "newData.isString() && newData.val() == newData.parent().parent().child('users/' + auth.uid + '/username').val()" 
     } 
    } 
    } 
} 

我也改變了父()的東西,但它不會藏漢工作。我改爲4位父母,0位父母。同樣的錯誤。

回答

1

更新:問題來源於此驗證規則:

".validate": "newData.isString() && newData.val() == root.child('users/' + auth.uid + '/username').val()" 

你對當前根比較新的數據。由於剛創建的用戶/users/$uid不會存在。

你想要做的是比較新的數據與新的用戶節點。爲了得到這個節點上,您應該進行比較時,從newData導航到根:

".validate": "newData.isString() && 
    newData.val() == newData.parent().parent().child('users/' + auth.uid + '/username').val()" 

下面我將離開我的以前的響應,因爲它可以在學習證明是有用如何排查這樣的問題。

我剛剛把你的規則粘貼到我的項目中,簡化了一下,並且沒有任何問題地使用你的代碼。我不確定你爲什麼遇到問題。

代碼:

FIRAuth.auth()?.signInAnonymously(completion: { (user, error) in 
     let username = "puf" 
     let userID = FIRAuth.auth()?.currentUser?.uid 
     self.ref.child("42188459").updateChildValues([ 
      "users/\(userID!)/username": username, 
      "usernames/\(username)": userID! 
     ], withCompletionBlock: { (error, reference) in 
      if (error != nil) { 
       print("disallowed") 
       // Write was disallowed because username exists 
      } 
     }) 
    }) 

規則片段:

"users": { 
    "$uid": { 
     ".write": "$uid === auth.uid", 
     "username": { 
     ".write": "!data.exists() && newData.exists()", 
     } 
    } 
    }, 
    "usernames": { 
    "$username": { 
     ".write": "!data.exists() && newData.exists()", 
    } 
    } 

產生的JSON:

{ 
    "usernames" : { 
    "puf" : "DBP4Pw3uiwQfUaDJw1XBR8oFBUK2" 
    }, 
    "users" : { 
    "DBP4Pw3uiwQfUaDJw1XBR8oFBUK2" : { 
     "username" : "puf" 
    } 
    } 
} 
+0

我複製你的更新規則,並與舊的價值觀取代了它。但是,我仍然遇到錯誤。此錯誤發生在.validate行,我剛剛複製的規則。在Firebase中的模擬器中,我也收到錯誤消息。我有這些設置:寫入,位置:/用戶名/ dfggdfg /,json值:{key}:「value」 },驗證:是,然後執行。閱讀工作,但寫作仍然有一些問題。其餘規則與上述規定完全相同。我將更新我正在使用的當前規則。 XCode仍然給出相同的錯誤。 – NoKey