2017-02-12 70 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