【问题标题】:Allow Create And Read in all the cases But don't allow update if the data does not exist in firebase real time database在所有情况下都允许创建和读取但如果数据在 firebase 实时数据库中不存在,则不允许更新
【发布时间】:2021-11-12 08:36:15
【问题描述】:

我正在使用 fiebase 开发一个聊天模块,我的结构如下。

我的主节点是mychatexperiment

在其中我有另一个节点 ChatListing 和其他一些聊天键。

今天我在我的结构中设置了 setValues,当我在没有任何节点的情况下传递我的 url 时,它会删除我在父节点内的所有数据。

我想要的是设置规则

  1. 任何情况下都可以创建节点
  2. 在任何情况下都可以更新节点
  3. 无论如何都不能删除节点
  4. 只能更新或设置ChatListing里面的数据

我正在尝试使用它,但它不起作用。任何想法如何实现这些东西。

{
  "rules": {
         ".write": "!data.exists() || !newData.exists()",
         "read" : true
   }
}

注意:我没有使用任何身份验证,因此需要在没有任何身份验证的情况下实施规则

修改要求:

我有一个结构,其中我有一个父节点,在其中我有多个通过 firebase 生成的聊天键,在聊天键中我在该聊天中有一个单独的消息节点。 最重要的第二件事是我有一个名为 chatlisting 的节点,我在其中以独特的格式存储我的用户 ID,例如如果我的用户 ID 为 5,所以在聊天列表中我存储 5,在那个 5 中我有所有聊天键节点与我有关。

{
  "ChatListing": {
    "1126_2": { //userUnique key 

      "MjmhpHb6qR7VSkYzbjI": { // 1126 userid has this chat key and inside this chat last msg was welcome and its unread count is 0 
        "UnReadCount": 0,
        "lastmessage": "Welcome",
        "lastmessagetime": 1631870264251
      }
    },
    "4184_1": {
      "MjmhpHb6qR7VSkYzbjI": { // 4184 userid has this chat key as well and inside this chat last msg was welcome and its unread count is 1 
        "UnReadCount": 1,
        "lastmessage": "Welcome",
        "lastmessagetime": 1.6318646965369204E12
      }
    }

  },
  "MjmhpHb6qR7VSkYzbjI": { // chat key
    "-MjmhpQbBaL7EbHPHayA": { // mesg key
      "data": "Thankyou",
      "time": 1.6318646965369204E12,
      "type": 0,
      "user": 4184   // the msg is sent by this user
    },
    "-Mjn21A4067dT4emYe05": {  // another msg in the same chat
      "data": "Welcome",
      "time": 1631870264251,
      "type": 0,
      "user": 1126 // the msg is sent by this user
    }
  }
}

我想要的是设置没有人可以在父节点(ChatList 节点除外)内运行更新、设置或删除的规则。任何人都可以在父节点中创建聊天键和读取聊天键,他们无能为力。

但在聊天列表中,他们可以执行创建读取、设置和更新(而不是删除),因为我需要针对用户聊天更新此节点中的最后一条消息。

【问题讨论】:

  • 这能回答你的问题吗? How to add firebase database rules without authentication?。只需将对 /cars 的引用替换为 /ChatListing
  • @samthecodingman 是的,看起来很有帮助,让我试试。谢谢
  • 试过但不行,你能指导我@samthecodingman
  • 什么具体不起作用?诸如“我仍然可以创建节点”、“我可以删除我不应该删除的数据”之类的内容。
  • { "rules": { "ChatListing": { ".read": true, ".write": "!data.exists()" } } }

标签: firebase firebase-realtime-database firebase-security rules


【解决方案1】:

因此,重复使用我的other answer 涵盖的要点,您可以使用以下规则应用这些规则:

{
  "rules": {
    "ChatListing": {
      "$userid": { // the user's unique ID
        // anyone who knows this user ID can read their messages
        ".read": true,

        "$chatid": { // a chatroom the user is in

          // data stored here MUST have this shape (with nothing else)
          // {
          //   UnReadCount: number,
          //   lastmessage: string,
          //   lastmessagetime: number
          // }

          // Data may be created or updated, but not deleted

          ".validate": "newData.child('UnReadCount').isNumber() && newData.child('lastmessage').isString() && newData.child('lastmessagetime').isNumber()",

          "UnReadCount":     { ".write": "newData.exists()" },
          "lastmessage":     { ".write": "newData.exists()" },
          "lastmessagetime": { ".write": "newData.exists()" }
        }
      }
    },
    // when using $ keys at the same level as defined keys,
    // this rule will catch everything that doesn't match
    // the above rules
    "$chatId": { // a chatroom where messages can be sent
      // anyone who knows this chat ID can read its messages
      ".read": true, 

      "$msgId": { // a message in this chatroom

        // Data stored here MUST have this shape (with nothing else)
        // {
        //   data: string,
        //   time: number
        //   type: number,
        //   user: string, // see note
        // }

        // Data may be created, but not edited or deleted
        // change like above if needed

        ".validate": "newData.child('data').isString() && newData.child('time').isNumber() && newData.child('type').isNumber() && newData.child('user').isString()",
        
        "data": { ".write": "!data.exists()" },
        "time": { ".write": "!data.exists()" },
        "type": { ".write": "!data.exists()" },
        "user": { ".write": "!data.exists()" }
      }
    }
  }
}

注意事项:

  • 不要使用数字用户 ID,因为它们很容易被猜到,生成一些随机的东西。你甚至可以使用const userId = push(getReference(getDatabase())).key。考虑使用anonymous authentication 保护数据。
  • 与您的要求不同,我已将聊天中的消息设为不可变。一旦发送,任何人都无法编辑它们。这可以防止发件人以外的其他人进入并更改消息。通过身份验证,可以允许进行编辑,因为它更安全。
  • 注意与我的/cars example 不同的是,我没有将".read": true 放在数据库的根目录或/ChatListing。这可以防止有人出现并运行以下任一代码来提取所有存储的数据或一次提取所有存储的用户 ID,这将允许他们找到不适合他们的消息。但它并不能防止暴力破解数据。
const rootRef = ref(getDatabase());

rootRef
  .then((snapshot) => {
    console.log(snapshot.val()) // all data in database!
  });

const chatListingRef = ref(getDatabase(), "ChatListing");

chatListingRef
  .then((snapshot) => {
    const usersArray = [];
    const chatIdSet = new Set();
    snapshot.forEach(userData => {
      usersArray.push(userData.key)
      userData.forEach(lastChatData => chatIdSet.add(lastChatData.key));
    });
    
    // logs all user IDs in the database!
    console.log("User IDs:", usersArray)

    // logs all chatroom IDs in the database!
    console.log("Chatroom IDs:", [...chatIdSet]) 
  });

【讨论】:

    猜你喜欢
    • 2019-03-29
    • 2018-08-12
    • 1970-01-01
    • 2020-03-22
    • 2023-04-10
    • 1970-01-01
    • 2021-02-20
    • 2019-07-22
    • 2021-08-27
    相关资源
    最近更新 更多