Firebase数据库权限被拒绝,尽管读/写权限设置为true。

38

我在我的简单Android应用程序中写入Firebase数据库时遇到了问题。我已将数据库规则设置为公共:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

创建了一个简单的类 Message:
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

public class Message {
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    DatabaseReference dbRef = database.getReference();
    public String sender;
    public String message;

    public Message(){}

    public Message(String sender, String message) {
        this.sender = sender;
        this.message = message;
    }
}

并设置一个按钮执行 onClick 方法 writeNewMessage,下面是关键代码:

int counter = 0;

public void writeNewMessage(View view) {

        counter += 1;
        Message messageToWrite = new Message("John", "Simple message: " + counter);
        String messageId = String.valueOf(counter);

        dbRef.child("users").child(messageId).setValue(messageToWrite);
    }

运行时,我收到了以下错误信息:
W/RepoOperation: setValue at /users/1 failed: DatabaseError: Permission denied

我知道这个问题似乎很简单,而且可能已经被重复了,但是我还没有发现有人在没有涉及身份验证或其他组件的情况下问这个问题。问题的简单性是最令我困惑的。

编辑:我也找到了这个错误:

Failed to load module descriptor class: Didn't find class "com.google.android.gms.dynamite.descriptors.com.google.firebase.auth.ModuleDescriptor"

嗯...规则看起来不错,所以听起来很奇怪。你确定保存/发布了规则吗? - Frank van Puffelen
我点击了发布按钮并成功地尝试了模拟器,所以据我所知它已经发布了! - Ben
非常奇怪。有几件事情需要检查:首先,请检查您的google-services.json文件,并确保您使用的项目是您期望的项目。其次,您可以尝试从项目中删除auth(如果存在firebase-auth的gradle依赖项,请将其注释掉),看看是否有任何不同? - Ian Barber
注释掉firebase-auth在我的情况下没有起作用,但我认为这是因为我在google-services.json上遇到了问题。我在设置时出现了错误,所以我在Firebase上重新创建了整个项目,最终一切都好了。非常感谢! - Ben
顺便提一下,最好在“Message”类之外实例化数据库并获取对它的引用。 - Sumit Jha
7个回答

62

我一直在更改Firestore规则,而不是数据库... 希望这对像我这样的蒟蒻有所帮助。

这里输入图片描述


请将代码作为文本包含在内。同时,您似乎在称呼 OP 为蠢货? - Artemis
17
没有需要包含的代码。我不是在说提问者愚蠢,而是那些犯了和我一样错误的人。我相信他们可以克服被称为愚蠢的感觉。 - Zogrof
1
没错,兄弟,就是这样,但这不是你的问题,我们已经习惯了默认设置实时数据库。 - Med Karim Garali
4
这是我的问题。谢谢。 - dominicoder
2
非常滑稽的错误 :/ - ruben

36

完整解决方案:

1). 首先进入认证选项卡,选择登录方式并打开匿名登录。

2). 其次进入数据库选项卡,并编写规则。

{
"rules": {
".read": true,
".write": true
}}

第三步,转到存储选项卡并编写以下规则

service firebase.storage {
 match /b/myapplicationname-f2266.appspot.com/o {
 match /{allPaths=**} {
 allow read, write;
}}}

注意:此解决方案仅用于测试目的,按照以下步骤操作将会向公众授予读写您的数据库的权限。


1
对我来说不起作用...当我按照第二步中在数据库中添加规则时,Firebase 给出错误,它无法识别 {ruels} 和后续代码...在第二步中确切地放置这段代码在哪里? - Abdul Waheed
1
如果您对此答案感到困惑,请确保在单击数据库侧边栏选项后,选择实时数据库并更改该数据库的规则,而不是默认的“Cloud Firestore”。请参阅Zogrof的答案。 - Axel
应该没问题,先进行第一步,将 Firebase-Auth 添加到您的项目实现中 implementation 'com.google.firebase:firebase-auth:18.1.0' - Douglas Mesquita

29

这似乎是与您的google-services.json有关的问题。

请确保应用程序名称和客户端ID与Firebase控制台中的相同。

如果您不确定,请从项目控制台重新下载google-services.json并将其添加到您的项目中。


1
非常顺利地完成了。 - Jacob
如果使用React Native会发生什么? - Jaimin Modi
1
嗨,devprashant,我在尝试将空字符串添加到当前用户ID旁边的数据库时也遇到了这个错误,但我的google-services.json是正确的,并且数据库是公共的。 - Khanyisa Fante
google-services.json 的位置应该位于 ./android/app 文件夹中,而不是 ./android。 - Marek

2

我不是完全确定问题出在哪里,但我只是从Firebase中删除了我的项目并重新创建了它,删除并安装新的google-services.json,第二次运行就完美地解决了。

幸运的是,这是一个测试应用程序,我的数据库是空的,但如果您遇到此情况并且在自己的帐户中存储有有价值的信息,我建议在尝试此解决方案之前先将其导出。


我建议在尝试此解决方案之前先将其导出。不,根本不要这样做... - mathematics-and-caffeine

1

这种错误的原因也可能在文档https://firebase.google.com/docs/database/android/start中描述的内容中。

注意:若要获取除us-central1默认数据库之外的数据库引用,必须将数据库URL传递给getInstance()(或Kotlin+KTX database())。对于us-central1默认数据库,可以调用不带参数的getInstance()(或database)。 您可以在Firebase控制台的Realtime Database部分找到实时数据库URL。它将采用以下格式 https://.firebaseio.com(用于us-central1数据库)或https://.firebasedatabase.app(用于所有其他位置的数据库)。


1
也许你应该将规则设置为: (我曾经遇到同样的问题,这对我有用。)
// These rules require authentication
    {
      "rules": {
        ".read": "auth != null",
        ".write": "auth != null"
      }
    }

嗨@Vandre,我在哪里应用这个规则? - MARSH

0

好的,我尝试了上面所有的解决方案但都失败了。 过了一会儿我发现我的项目有两个模块,而我在第二个模块中调用了Firebase而不是主要的模块,所以解决办法是也将第二个模块添加到Firebase项目中,然后它就可以工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接