【问题标题】:Firebase Database Rules private nodesFirebase 数据库规则专用节点
【发布时间】:2016-10-19 06:45:12
【问题描述】:

我正在开发一个groceryItem 应用程序,用户可以在其中添加商品,并且只能看到他们自己的商品。
我使用childByAutoId 添加我的项目,并为每个项目获取唯一的密钥条目(参见图片#1)。

每个项目都有 3 个属性。 addedByUser 是经过身份验证的用户的 UID,当然还有名称和数量。

我在设置规则以便只有用户可以看到他们自己的项目时遇到问题。我目前的规则是这样的(见图#2)。

如果我使用其他用户登录,他可以阅读所有项目。所以我的问题是: 如何让创建它们的用户能够阅读项目?

我认为itemsaddedByUser 之间存在差距,因为我在两者之间有childByAutoId。如果您有任何解决方案或提示我可以如何以更好的方式构建它,请随时帮助我。

提前致谢!

【问题讨论】:

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


【解决方案1】:

$addedByUser 在这个例子中可能出现在错误的位置,因为它不是项目的“嵌套子”,而是子项目的属性。我建议(未对此进行测试)您将寻找以下内容:

"items": {
  "$item": {
    ".read": "data.child('addedByUser').val() === auth.uid"
  }
}

本文摘自Firebase docs

有数据:

{
  "messages": {
    "message0": {
      "content": "Hello",
      "timestamp": 1405704370369
    },
    "message1": {
      "content": "Goodbye",
      "timestamp": 1405704395231
    },
    ...
  }
}

规则可以是:

{
  "rules": {
    "messages": {
      "$message": {
        // only messages from the last ten minutes can be read
        ".read": "data.child('timestamp').val() > (now - 600000)",

        // new messages must have a string content and a number timestamp
        ".validate": "newData.hasChildren(['content', 'timestamp']) && newData.child('content').isString() && newData.child('timestamp').isNumber()"
      }
    }

} }

这将阻止不正确的用户读取其他人的(单数)项目,并且在您的示例中将阻止用户 SZ825V... 对“items/-KKTDD...”执行读取,但是如果用户 SZ825V 要对“项目”执行读取,则读取将完全失败,因为用户正在尝试读取自己的文档以及其他人的文档。这是 firebase 中的一个重要概念,规则以原子方式运行 - 也就是说,如果读取的一部分失败,则整个读取都会失败。另一种说法是规则不充当过滤器。 如果这是您正在寻找的功能,则可能需要重新排列您的结构。一个例子可以如下:

{
  "users": {
    "abcdef-user-id": {
      "items": {
        "fjeiwofjewio": {
           "name": "apple",
           "qty": "23"
        }
      }
    },
    "ghijkl-user-id": {
      "items": {
        "regrewgreh": {
          "name": "passionfruit",
          "qty": "18"
        }
      }
    }
}

安全规则可能是:

.. {
     "users": {
       "$userId": {
          ".read": "auth.uid === $userId"
       }
     }
   }

上述方法假设您只想允许用户读取其用户自己的数据树中的项目,其他人将无法看到任何其他用户的项目。如果您确实希望其他用户看到其他用户的某些项目,则需要再次采用不同的方法,这将是另一个 SO 问题。

【讨论】:

  • ref.child("items").observeEventType(.Value, withBlock: { snapshot in var newItems = [Item]() for item in snapshot.children { print(item) let item = Item (snapshot: item as! FIRDataSnapshot) newItems.append(item) } 在我的 iOS 应用程序中,我在这个 ref 上调用了 observeEvent。现在我什么都读不出来:(
  • 这是因为 firebase 权限的原子性。如果您读取“项目”列表并且任何读取失败(即因为您试图读取属于另一个用户的项目),那么整个读取失败,因此项目不返回任何内容。规则不充当过滤器。我的回答与能够阅读用户的项目并阻止其他用户阅读有关,而不是试图完整地阅读项目列表。不同的结构可能是合适的,我将在答案中添加。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 2021-04-03
  • 2017-07-15
  • 2021-08-16
  • 2019-12-17
相关资源
最近更新 更多