Firebase数据库:按值查找而无需索引访问

时间:2016-12-27 15:43:46

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

我想让用户按价值找到记录,但我不希望他们能够列出所有记录。

例如,我想创建一个wiki,我希望某些页面只能通过直接网址访问。

我知道我可以在记录级别上提供读取权限,并且用户无法读取所有密钥,但是我只能将其限制为只允许使用密钥的字符,而我可能需要使用/和其他字符。

所以我会在它的path属性中存储一条东西的路径,然后按path查找该东西;

// database structure
things
    -KNi4OQXGXsHKYHVuTln
        path: "should/not/be/listed/anywhere"

我想让用户只有在知道路径时才能找到它。

问题是我只能通过使用/thingsorderByChild搜索equalTo来找到该内容:

// request with javascript
firebase.database()
    .ref('/things').orderByChild('path')
    .equalTo("should/not/be/listed/anywhere")
    .once('value', s=>{  });

这意味着我必须提供对/things的读取权限:

// database security rules
{
    "rules": {
        "things": {
            ".read": true,
            ".indexOn": ["path"],
            "$thingId": {
                ".validate": "newData.hasChildren(['path']) && newData.child('path').isString()"
            }
        }
    }
}

这有效地让任何人都可以看到我拥有的所有东西。有没有办法避免这种情况?

如果没有,这是否意味着Firebase强制我在想要通过属性值找到所有内容时公开我的内容?

2 个答案:

答案 0 :(得分:2)

为了能够在Firebase数据库中找到某些内容,您必须具有对它的读取权限。没有办法避免这种情况。

我们通常将此称为"规则不是过滤器"您可以在documentationthis answersearching for "rules are not filters" on Stack Overflow中找到有关它的更多信息。

如果您想提供无需访问的搜索,您必须设置自己的搜索服务,该服务运行受信任的代码,然后公开匹配的项目'路径回到客户端。

在Firebase前设置此类搜索服务的常用方法是使用Firebase Flashlight library for ElasticSearch或使用云搜索服务,例如Algolia

答案 1 :(得分:1)

我知道我应该能够避免为这样简单的事情维护服务器,所以我回答了我自己的问题。

我的实际问题是,我想让用户在知道密钥时访问某些内容,但并不希望他们看到所有内容。我可以通过提供事物级访问并使用路径作为键来做到这一点,但是键不允许我使用/,当然我也希望我的东西结构是扁平的。 / p>

再看一遍之后,我找到了limitations on keys in firebase,这是

  • 最多768个字符
  • 禁止使用的字符:. $ # [ ] /
  • 一些允许的字符:\ ! @ % & ? : ; , * = + < > ( ) | " ' ^ ~ - _

因此,我可以简单地创建一个简单的地图,将禁止的字符转换为允许的字符,并将路径用作键,这解决了我的问题:用户只有在知道路径时才能访问事物,而路径可以看到作为网址。