firebase数据库安全规则中存在未指定的索引警告



我制作了一个云功能来删除过期的警报消息,我的数据结构如下:

Alerts
|-{country1}
|-{c1_state1}
|-{key}
|-msg: "bla bla"
|-end: 1601251200000
|-{c1_state2}
|-{key}
|-msg: "bla bla"
|-end: 1601251200000
|-{country2}
|-{c2_state1}
|-{key}
|-msg: "bla bla"
|-end: 1601251200000
|-{c2_state2}
|-{key}
|-msg: "bla bla"
|-end: 1601251200000

查看日志消息,我注意到for循环(states变量(中的每个查询都有很多警告。

[22020-09-29T02:04:28.585Z]@firebase/database:firebase警告:使用未指定的索引。您的数据将在客户端上下载和筛选。考虑添加";。indexOn":"结束";位于/Alers/BR/RR的安全规则,以获得更好的性能

我在firebase数据库中搜索了很多关于设置规则的内容,但我无法将这些规则应用到工作中。在我的数据库中,我在国家和州中循环,这就是为什么我使用通配符($coutry$state(

{
/* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
"rules": {
".read": "auth != null",
".write": "auth != null",
"Alerts": {
"$country": {
"Sstate": {
".indexOn": ["end"]
}
}
}
}
}

我的功能正常工作,数据会按预期删除,但警告不断。

exports.closeAnnouncementsBRTZ3 = functions.pubsub
.schedule('10 0 * * *')
.timeZone('America/Sao_Paulo') // Users can choose timezone - default is America/Los_Angeles
.onRun((context) => {
const expireTime = 1601251200000;
const ref = admin.database().ref().child('Alerts').child('BR');

const states = ['AC', 'AM', 'MS', 'MT', 'RO', 'RR'];

return Promise.all(states.map(async (state) => {
return await ref.child(state).orderByChild('end').endAt(expireTime).once('value', (dataSnapshot) => {
console.log('await dataSnapshot: ', state);
if (dataSnapshot.val() !== null) {
dataSnapshot.forEach(childSnapshot => {
console.log('child to be removed: ', childSnapshot.key);
childSnapshot.ref.remove();
});
}
});
}));

});

那么,如何在没有警告的情况下正确设置规则,从而提高查询的性能呢?

事实上,如果您的应用程序目前没有太多数据,那么您的查询会正常工作,甚至可能感觉不到性能问题。然而,事实上,使用通配符可能会影响您的性能,index可能会对您有所帮助,因为它不依赖于客户端对其进行筛选和执行。

然而,正如Firebase Engineer提供的对此问题的评论中所澄清的那样,不幸的是,不可能设置通配符索引。如本例所示,更改数据库的结构将帮助您解决此问题,因为您可以以一种可以轻松使用索引并提高性能的方式对其进行建模。

总之,您需要更改数据库结构才能提高性能,因为索引不能像现在这样使用通配符。

我通过添加"解决了这个问题;。indexOn":"结束">在每个节点上,即使有些节点还不存在。

{
/* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
"rules": {
".read": "auth != null",
".write": "auth != null",
"Alerts": {
"BR": {
"AC": {
".indexOn": ["end"]
},
"AM": {
".indexOn": ["end"]
},
"MS": {
".indexOn": ["end"]
},
"MT": {
".indexOn": ["end"]
},
"RO": {
".indexOn": ["end"]
},
"RR": {
".indexOn": ["end"]
}
}
}
}
}

这不是一种方便的解决方法,因为我们必须为项目中的每个可能节点设置规则。但一旦完成。。。完成了!

最新更新