【问题标题】:Loading Firebase SDKs via reserved URL is giving "Permission denied" error通过保留 URL 加载 Firebase SDK 会出现“权限被拒绝”错误
【发布时间】:2021-01-13 20:23:55
【问题描述】:

我已设法使用文档中所述的保留 URL 部署我的 Firebase 站点。当我的数据库规则设置为“true”时,一切正常,但是一旦我尝试输入规则,它就会抛出错误“Permission Denied”

我没有更改 index.html 的默认代码,除了添加简单的行来尝试并包含我尝试读取或写入的节点的路径。我已经设法在 NodeJS 和 FirebaseUI 中使用这些规则通过另一个站点登录,但我似乎无法按照文档中的建议自动加载我的 sdk 配置。谁能提供一些见解?谢谢。

编辑:我刚刚成功尝试使用 firebase.auth() 创建新用户。显然,我的配置实际上已被自动导入。我不知道为什么我无法读取或写入数据库,除非作为规则范围内的用户。我认为 Admin SDK 会覆盖所有数据库规则。我错过了什么明显的东西吗?

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Welcome to Firebase Hosting</title>

  <!-- update the version number as needed -->
  <script defer src="/__/firebase/7.21.1/firebase-app.js"></script>
  <!-- include only the Firebase features as you need -->
  <script defer src="/__/firebase/7.21.1/firebase-auth.js"></script>
  <script defer src="/__/firebase/7.21.1/firebase-database.js"></script>
  <script defer src="/__/firebase/7.21.1/firebase-storage.js"></script>
  <!--script src="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.js"></script-->
  <!-- initialize the SDK after all desired features are loaded -->

  <script defer src="/__/firebase/init.js"></script>

  <style media="screen">
    body {
      background: #ECEFF1;
      color: rgba(0, 0, 0, 0.87);
      font-family: Roboto, Helvetica, Arial, sans-serif;
      margin: 0;
      padding: 0;
    }

    #message {
      background: white;
      max-width: 360px;
      margin: 100px auto 16px;
      padding: 32px 24px;
      border-radius: 3px;
    }

    #message h2 {
      color: #ffa100;
      font-weight: bold;
      font-size: 16px;
      margin: 0 0 8px;
    }

    #message h1 {
      font-size: 22px;
      font-weight: 300;
      color: rgba(0, 0, 0, 0.6);
      margin: 0 0 16px;
    }

    #message p {
      line-height: 140%;
      margin: 16px 0 24px;
      font-size: 14px;
    }

    #message a {
      display: block;
      text-align: center;
      background: #039be5;
      text-transform: uppercase;
      text-decoration: none;
      color: white;
      padding: 16px;
      border-radius: 4px;
    }

    #message,
    #message a {
      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
    }

    #load {
      color: rgba(0, 0, 0, 0.4);
      text-align: center;
      font-size: 13px;
    }

    @media (max-width: 600px) {

      body,
      #message {
        margin-top: 0;
        background: white;
        box-shadow: none;
      }

      body {
        border-top: 16px solid #ffa100;
      }
    }
  </style>
</head>

<body>



  <div id="message">
    <h2>Welcome</h2>
    <h1>Firebase Hosting Setup Complete</h1>
    <p>You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something
      extraordinary!</p>
    <a target="_blank" href="https://firebase.google.com/docs/hosting/">Open Hosting Documentation</a>
  </div>
  <p id="load">Firebase SDK Loading&hellip;</p>

  <script>


    document.addEventListener('DOMContentLoaded', function () {

      firebase.database().ref('/test').set('just a test')

      // // ????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
      // // The Firebase SDK is initialized and available here!
      //
      // firebase.auth().onAuthStateChanged(user => { });
                 firebase.database().ref('/users').on('value', snapshot => { 
         console.log(snapshot.val())
         console.log(snapshot.key)});
      // firebase.messaging().requestPermission().then(() => { });
      // firebase.storage().ref('/path/to/ref').getDownloadURL().then(() => { });
      //
      // // ????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

      try {
        let app = firebase.app();
        let features = ['auth', 'database', 'messaging', 'storage'].filter(feature => typeof app[feature] === 'function');
        document.getElementById('load').innerHTML = `Firebase SDK loaded with ${features.join(', ')}`;
      } catch (e) {
        console.error(e);
        document.getElementById('load').innerHTML = 'Error loading the Firebase SDK, check the console.';
      }
    });
  </script>
</body>

</html>

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

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

【问题讨论】:

    标签: javascript html google-apps-script firebase-realtime-database firebase-authentication


    【解决方案1】:

    您的网页使用的不是 Admin SDK,而是常规的 JavaScript SDK。这意味着您的代码必须遵守您自己的安全规则和这一行:

    firebase.database().ref('/users').on('value', snapshot => { 
    

    不起作用,因为您的安全规则未授予任何人读取 /users 节点的权限。

    如果您希望用户从数据库中读取他们自己的节点,那就是:

    firebase.auth().onAuthStateChanged(user => { 
      if (user) {
        firebase.database().ref('/users').child(user.uid).on('value', snapshot => { 
          ...
    

    【讨论】:

    • 我想在运行我的脚本时拍摄一些安全管理节点的快照。我是否必须以所有者身份登录并将其添加到规则中,或者有没有办法从 html 中使用 admin sdk?
    • Admin SDK 只能在受信任的环境中使用,例如您的开发机器、您控制的服务器或 Cloud Functions。它不能用于 HTML+JavaScript 页面。在常规 JavaScript SDK 中无法成为“所有者”。来自该 SDK 的所有访问都必须遵守您配置的安全规则。
    • 谢谢弗兰克。我现在觉得有点傻。我只是觉得很奇怪,我能够对用户使用 firebase.auth() 做这么多,但我无法访问数据库。总的来说,我对这一切仍然很陌生,作为 52 岁的新爱好/职业转变,我并没有很快学会它:)
    • 嗨弗兰克,我已经尝试过了,但因为我是论坛的新手,系统不允许我投票。它说我需要 15 个声望。再次感谢。非常受欢迎。
    • 是的,这确实是一个要求。如果它回答了您的问题,您仍然可以接受答案。
    猜你喜欢
    • 2016-09-25
    • 1970-01-01
    • 2016-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    相关资源
    最近更新 更多