简体   繁体   English

检查唯一的用户名时,Firebase权限被拒绝

[英]Firebase permission denied when checking unique username

I want to check if the username already is in use. 我想检查用户名是否已被使用。 This function gets called when the current user does not have a child of "username": 当前用户没有“ username”的子代时,将调用此函数:

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
            }
    })
}

In combination with this rules: 结合以下规则:

{
  "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()"
      }
    }
  }
}

I got the answer from: https://groups.google.com/forum/#!topic/firebase-talk/dA1Lkykd-tk I get this error message: 我从以下网址得到了答案: https : //groups.google.com/forum/#!topic/firebase-talk/dA1Lkykd-tk我收到此错误消息:

[Firebase/Database][I-RDB03812] updateChildValues: at / failed: permission_denied [Firebase / Database] [I-RDB03812] updateChildValues:位于/失败:Permission_denied

I am not sure why this wont work. 我不确定为什么这行不通。 I also tried this answer: Firebase android : make username unique But this did not work for me. 我还尝试了以下答案: Firebase android:使用户名唯一,但这对我不起作用。 There is something wrong with the rules but I dont know what. 规则有问题,但我不知道是什么。

Update, little change in rules, still same error: 更新,规则变化不大,仍然存在相同错误:

{
  "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()"
      }
    }
  }
}

I also changed the parent() things, but it wouldn't work aswell. 我也更改了parent()的东西,但是它也不能正常工作。 I changed to 4 parents, and 0 parents. 我更改为4个父母和0个父母。 Same error. 同样的错误。

Update: The problem comes from this validation rule: 更新:问题来自此验证规则:

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

You're comparing the new data against the current root. 您正在将新数据与当前根进行比较。 Since the user has just been created /users/$uid won't yet exist. 由于刚刚创建了用户,因此/users/$uid尚不存在。

What you want to do is compare the new data against the new users node. 您要做的是将新数据与用户节点进行比较。 To get to this node, you should navigate from newData up to the new root when comparing: 要到达此节点,在进行比较时,您应该从newData导航到新的根目录:

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

I'll leave my previous response below, since it may prove useful in learning how to troubleshoot a problem like this. 我将下面的答复留在下面,因为它可能有助于学习如何解决此类问题。

I just pasted your rules into a project of mine, simplified them a bit and used your code without problems. 我只是将您的规则粘贴到我的项目中,对其进行了一些简化,并且使用了您的代码而没有出现问题。 I'm not sure why you're having a problem. 我不确定您为什么遇到问题。

The code: 编码:

    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
            }
        })
    })

The rules snippet: 规则片段:

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

The resulting JSON: 结果JSON:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM