/ users的监听器失败:permission_denied

时间:2017-07-20 14:07:09

标签: ios swift firebase firebase-realtime-database firebase-authentication

我使用Firebase进行注册流程。当我检查数据库中是否已存在电子邮件时,如下所示:

refUsers.queryOrdered(byChild: "email").queryEqual(toValue: emailText).observeSingleEvent(of: .value, with: { snapshot in

      if (snapshot.value is NSNull) {
            print("Unique email")

            // Move to Password View.
            let passwordViewController = self.storyboard?.instantiateViewController(withIdentifier: "PasswordViewController") as! PasswordViewController

            self.navigationController?.present(passwordViewController, animated: true, completion: nil)

            // Pass the emailText to the last View of the flow.
            self.singleton.sharedInstance.emailText = emailText!

      }
      else {
            print("Duplicate email")
      }  
})

问题是,我没有权限查看数据库中的/用户因为我的规则是:

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null"
  }
}

我知道我可以使用Auth.auth().createUser查找电子邮件是否重复,但这不仅仅是我在注册流程中检查的电子邮件。我也使用相同的方法来获取唯一的用户名。我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:3)

正如您所看到的,这不是最好的方法。您不应该手动检查电子邮件是否已经存在 - Firebase可以在用户注册时为您执行此操作,为什么您不想使用它?

您需要的是一种不同的方法。我现在可以想到两种方式:

首先:

您可以向Firebase添加新规则,例如:

"rules": {
    "usernames": {
      ".read": true,
      ".write": "auth != null"
    },
    "emails": {
      ".read": true,
      ".write": "auth != null"
    }
  }
}

您在此处创建一个名为usernames的新节点,每个用户都可以访问和读取该节点。 在这里,您应该拥有注册用户拥有的所有用户名的副本,并在注册时检查用户的用户名是否已经在此节点内。

第二种方式:

您可以稍微修改注册流程,让用户在没有用户名的情况下注册。创建帐户后,您可以设置用户名。有了一个很好的流程,它看起来都是相同的注册形式。

<强>更新 使用上述规则,用户应该能够在不注册的情况下从emailsusernames进行阅读。这样您就可以获取数据并比较电子邮件或用户名是否已被使用。

只需确保在用户注册时将您的电子邮件和用户名插入这两个节点。

答案 1 :(得分:0)

虽然@ZassX的回答帮助了我,但我已经了解了对于那些像我这样困惑的人来说,这是一个很好的方法。

最好的方法是在/users "auth != null"规则下保护用户数据安全。仅向所有人显示用户的元数据,其中仅包含每个用户的电子邮件和密码。例如:

<强>数据库

{
    “metaData”: { 
        uid: { 
            “email”: …,
            “password”: …
        }
    },
    “users”: { 
        uid: { 
            “email”: …,
            “password”: …
            // other information
        }
    }
 }

安全

{
    "rules": {
        “metaData”: { 
            “.read”: true,
            “.write”: “auth !== null”
        },
        “users”: { 
            “.read”: “auth !== null”,
            “.write”: “auth !== null”
        }
    }   
}

现在可以匹配metaData中的信息,而无需先对用户进行身份验证。当然,随着您添加更多安全性,这会变得更加复杂,但为了便于理解,就是这样。