防止写入不存在firebase的节点

时间:2018-04-03 04:10:29

标签: firebase firebase-realtime-database

我有一个有趣的firebase数据库问题。我将带您了解它是如何产生的。

步骤1:用户A发布了一个节点

      "20180104" : {
    "-L2DNnIkER8XaBOI4n9l" : {
      "ImageName" : "EaWpwOXjmFsVatbkBM6V1307.jpg",
      "favoriteCount" : 12,
      "fileURL" : "https://storage.googleapis.com/...",
      "viewCount" : 20,
      "reportCount" : 2,
      "setID" : "-L2DNknqYN0IzTUN6pe-",
      "thumbFileUrl" : "https://storage.googleapis.com/...",
      "user" : "uid"
    },
    "-ABCDnIkER8XaBOI4n9l" : {
      "ImageName" : "EaWpwOXjmFsVatbkBM6V1307.jpg",
      "favoriteCount" : 3,
      "fileURL" : "https://storage.googleapis.com/...",
      "viewCount" : 8,
      "reportCount" : 2,
      "setID" : "-L2DNknqYN0IzTUN6pe-",
      "thumbFileUrl" : "https://storage.googleapis.com/...",
      "user" : "uid"
    },

第2步:用户B从firebase中提取此信息。现在,他们在应用程序中本地拥有JSON。

步骤3:用户A从firebase中的节点删除第二个图像密钥。

Step4:firebase中生成的JSON为:

          "20180104" : {
    "-L2DNnIkER8XaBOI4n9l" : {
      "ImageName" : "EaWpwOXjmFsVatbkBM6V1307.jpg",
      "favoriteCount" : 12,
      "fileURL" : "https://storage.googleapis.com/...",
      "viewCount" : 20,
      "reportCount" : 2,
      "setID" : "-L2DNknqYN0IzTUN6pe-",
      "thumbFileUrl" : "https://storage.googleapis.com/...",
      "user" : "uid"
    }, 
    // second node is now deleted

步骤5:现在用户A决定“喜欢”第二张照片,导致写入数据库。

第6步:我们在firebase中生成的数据库:

          "20180104" : {
    "-L2DNnIkER8XaBOI4n9l" : {
      "ImageName" : "EaWpwOXjmFsVatbkBM6V1307.jpg",
      "favoriteCount" : 12,
      "fileURL" : "https://storage.googleapis.com/...",
      "viewCount" : 20,
      "reportCount" : 2,
      "setID" : "-L2DNknqYN0IzTUN6pe-",
      "thumbFileUrl" : "https://storage.googleapis.com/...",
      "user" : "uid"
    },
    "-ABCDnIkER8XaBOI4n9l" : {
      "favoritecount": 13
      // now we have corrupted data :(
    }

我想阻止步骤6中的最终写入。安全规则方面但似乎无法弄清楚它们是如何工作的。说“..如果父键不存在,不写信给它?”

2 个答案:

答案 0 :(得分:1)

假设您的pic密钥没有像您的示例中那样重复,您可以阻止对不存在的节点进行写入:

"picDirectory" {
    "$picID": {
       ".write": "data.exists()"
    }
}

以下是相关的docs

答案 1 :(得分:0)

您的通用ID实际上是重复的,即-L2DNnIkER8XaBOI4n9l是完全相同的密钥。图像也是完全相同的图像。看起来每个图像都有一个唯一的密钥。修复后,使用事务来处理共享计数器,例如喜欢或启动。

Save data as transactions

  

例如,在示例社交博客应用中,您可以允许   用户可以发布明星和非明星帖子并跟踪帖子中有多少个明星   收到如下:

function toggleStar(postRef, uid) {
  postRef.transaction(function(post) {
    if (post) {
      if (post.stars && post.stars[uid]) {
        post.starCount--;
        post.stars[uid] = null;
      } else {
        post.starCount++;
        if (!post.stars) {
          post.stars = {};
        }
        post.stars[uid] = true;
      }
    }
    return post;
  });
}
     

使用交易可以防止星号不正确   多个用户同时或客户端同一个帖子   陈旧的数据。如果事务被拒绝,服务器将返回   客户端的当前值,再次使用   更新的价值。这将重复,直到交易被接受或您   中止交易。