客户端没有权限访问 Firebase 中所需的数据。

39
我有一个页面调用了控制器中的addCheckin()方法。在控制器中,我尝试创建如下引用:
var ref = firebase.database().ref("users/" + $scope.whichuser + "/meetings/" +$scope.whichmeeting + "/checkins");

$scope.whichuser$scope.whichmeeting是我从另一个路由传递的$routeParams。以下是我的签到控制器 -

myApp.controller("CheckinsController",
    ['$scope','$rootScope','$firebaseArray','$routeParams','$firebaseObject',
    function($scope,$rootScope,$firebaseArray,$routeParams,$firebaseObject){

        $scope.whichuser = $routeParams.uid;
        $scope.whichmeeting = $routeParams.mid;

        var ref = firebase.database().ref("users/" + $scope.whichuser + "/meetings/" +$scope.whichmeeting + "/checkins");

        $scope.addCheckin = function(){
            var checkinInfo = $firebaseArray(ref);
            var data={
                firstname:$scope.firstname,
                lastname:$scope.lastname,
                email:$scope.email,
                date:firebase.database.ServerValue.TIMESTAMP
            }

            checkinInfo.$add(data);
        }

}]);/*controller*/

我这里出现了两个错误-

错误1:

Error: permission_denied at /users/Vp2P1MqKm7ckXqV2Uy3OzTnn6bB3/meetings: 客户端无权访问所需的数据。

错误2:

Error: permission_denied at /users/Vp2P1MqKm7ckXqV2Uy3OzTnn6bB3/meetings/-KT5tqMYKXsFssmcRLm6/checkins: 客户端无权访问所需的数据。

我想要实现的目标是-

enter image description here


3
请将你的 Firebase 规则添加到问题中。这些规则实际上是导致权限被拒绝错误的原因。 - André Kool
4
除了提供规则之外,你在问题中还包含了JSON树的图片。请使用文本格式替换该图片,你可以通过在Firebase数据库控制台中点击导出按钮轻松获得JSON文本。以文本形式呈现JSON使其可搜索,允许我们轻松地使用它来测试你的实际数据并在答案中使用它,总的来说,这是一个好习惯。 - Frank van Puffelen
{ "rules": { ".read": true, ".write": true } } @AndréKool - Aakash Thakur
12个回答

45
似乎问题出在读写权限上。
1. 进入您的应用的Firebase控制台。 2. 从侧边菜单中选择数据库 --> 从上方选项卡中选择规则。 3. 更新您的规则。
以下是一个允许任何人编辑数据的规则示例:
    {
        "rules": {    
            ".read": true,
            ".write": true
        }
    }

警告:请谨慎使用上述规则,因为它们允许任何人读写您的实时数据库中的所有内容。有关更多信息,请参阅Firebase文档。

71
虽然这样做可以解决错误,但会使数据库对全世界可读和可写。如果您进行此建议时包含警告将会更好。 - Frank van Puffelen
对我有用 :) - Naveen Kumar V
2
如果其他人也感到困惑(或者可能只是凌晨两点),Firebase的“实时数据库”和新的“Cloud Firestore [Beta]”服务是完全独立的实体,具有不同的API。 “Cloud Firestore”的等效规则可以在此处找到。在我的情况下,我已经正确配置了这个,但是尝试使用“实时数据库”API时,我没有调整相应的规则。 - Visualise
@Visualise 确实已经是凌晨2点了。非常感谢您的评论。我一直在绞尽脑汁,疯狂地想要理解问题所在。我一直在尝试访问“云火灾数据库”,但实际上我想使用“实时数据库”。 - ExpectoPatronum
无法相信这是最受欢迎的答案,这是一个至关重要的安全问题! - mrvnklm
显示剩余4条评论

14

默认情况下,Firebase项目使用Firestore作为数据库。

如果应用程序使用“Firebase实时数据库”,并且未配置其权限,则可能会出现此问题。Firebase实时数据库的读写权限应该被明确授予。

为此,在Firebase控制台中,Database > 在“Firestore Beta”旁边的下拉菜单中选择“实时数据库”> Rules > Set,然后设置Firebase实时数据库的读写权限。

{
/* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
"rules": {
".read": true,
".write": true
}
}
希望有所帮助!

谢谢,这很有帮助。{ /* 访问 https://firebase.google.com/docs/database/security 了解更多关于安全规则的信息。 */ "rules": { ".read": true, ".write": true } } - chia yongkang
Firebase项目默认使用Firestore作为数据库。但如果您直接链接到数据库URL(例如:databaseURL: "https://project-xyz.firebaseio.com"),则不适用此规则。 - Spencer Shattuck

10

所有提供的答案都存在安全问题,任何人都可以在您的数据库中编写/删除条目,这可能会导致巨大的成本和/或完全丢失数据,如果使用不当。

当然,您需要使用Firebase身份验证功能才能使用这些规则,但防止匿名写入访问应该是默认设置。下面的规则为每个人提供读取访问权限,同时保持安全性。

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

6

这些答案都没有提供设置实时数据库最安全的方法。

  • 您不希望任何人随意访问或写入您的数据库
  • 即使用户经过身份验证,您也不希望他们访问他人的数据

这个规则应该解决所有情况:

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}

3
请使用以下代码在Firebase中注册自己。
Firebase.auth()
            .createUserWithEmailAndPassword(email, password)
            .then((data) => console.log(data))
            .catch(error => console.log(error))

使用注册的电子邮件和密码进行身份验证,以下是代码:

Firebase.auth()
           .signInWithEmailAndPassword(email, password)
           .then((data) => console.log(data))
           .catch(error => console.log(error))

使用以下规则在您的实时数据库中:

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

然后,您就可以自动访问实时数据库中的数据了。

var ref = firebase.database().ref("users");
ref.on("value", function(snapshot) {
 snapshot.forEach(function(childSnapshot) {
  var childData = childSnapshot.val();
  var id=childData.id;
  console.log(childData);
 });
});

在退出登录时,添加以下命令以注销应用程序。
Firebase.auth().signOut()

1
为了向所有已认证用户授予权限,请前往Firebase Web控制台的数据库规则选项卡,并复制/粘贴以下规则:
{
   "rules": {
    ".read": "auth != null",
    ".write": "auth != null"    
    }
}

0

看起来 /users/{uid} 路由可以被写入,但无法从中读取。我将 /users 改为 /userx,它立即开始工作。


1
这只是一个错误的操作,users 没有什么特别的。 - Mugen

0
在我的情况下,问题只是Flutter中的Firebase选项未配置,所以我只需要手动执行FlutterFire配置即可。
如果您尚未设置FlutterFire CLI,请从此处进行设置。

0
规则: {".read": "auth != null", ".write": "auth != null"}

2
根据目前的写法,你的回答不够清晰。请编辑以添加更多细节,帮助其他人理解这如何回答所提出的问题。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - Community

0

您还可以指定允许的时间,例如:

从侧边菜单中选择数据库 --> 在上方选项卡中选择规则 --> 更新您的规则如下

{
  "rules": {
    ".read": "now < 1672384350000",  // 2022-12-30
    ".write": "now < 1672384350000",  // 2022-12-30
  }
}

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