Firebase 未定义索引
Firebase no index defined
我正在使用 Firebase 检索用户的一些数据。
我需要检索 只有一个用户 与 (gameSearching = true
).
我的数据如下:
Users
|
|_____ John
| |___ name: John Farmer
| |___ gameSearching: true
|
|_____ James
| |___ name: James Smith
| |___ gameSearching: false
|
|_____ Barbara
|___ name: Barbara Smith
|___ gameSearching: true
我正在运行宁此代码:
setData(('Users/' + you + '/'), {gameSearching: true});
var ref = new Firebase("https://grootproject.firebaseio.com/Users");
var child = ref.orderByChild("gameSearching");
child.on("child_added", function (data) {
var yourself = firebase.getAuth().password.email.split("@", 1)[0];
data.forEach(
function (childSnapshot) {
if (childSnapshot[i].val().gameSearching == true && childSnapshot[i].key() != yourself) {
var opponent = childSnapshot[i].key();
setData(('Users/' + opponent + '/'), {gameSearching: false});
setData(('Users/' + yourself + '/'), {gameSearching: false});
}
}
);
});
因为'data'有多个值,所以我用'data.forEach'来分隔。在那之后我可以在 'true' 上设置一个 'return' 这样我只会收到一个 'gameSearching: true'.
的用户
我的 firebase 规则:
{
"rules": {
".read": true,
".write": true,
".indexOn": "gameSearching"
}
}
当我 运行 此代码时,出现以下错误:
'Uncaught Error: No index defined for gameSearching'
我搜索过使用“.indexOn”在 'gameSearching' 上设置索引,但没有成功。
https://www.firebase.com/docs/security/guide/indexing-data.html
有人有示例或解决方案吗?
编辑:
我现在得到以下代码:
var ref = new Firebase("https://grootproject.firebaseio.com/Users");
ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1).on("child_added", function (data) {
var yourself = firebase.getAuth().password.email.split("@", 1)[0];
var opponent = data.key();
console.log(opponent);
setData(('Users/' + opponent + '/'), {gameSearching: false});
setData(('Users/' + yourself + '/'), {gameSearching: false});
console.log('ja');
});
我编辑了我的 firebase 规则:
{
"rules": {
".read": true,
".write": true,
"Users": {
".indexOn": "gameSearching"
}
}
}
indexOn 错误不会再显示了,太好了。但是 ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1
) 会 运行s 两次。我不知道这怎么可能。我正在使用 limitToFirst(1)`,所以我期望 1 child?
您的查询对数据进行排序,但未能对其进行筛选。如果将其更改为此,查询将仅匹配正在搜索游戏的用户:
var query = ref.orderByChild("gameSearching").equalTo(true);
这大致转化为 WHERE gameSearching = true
的 SQL,这就是您在上一个问题中提出的问题。请注意,我将变量称为 query
,因为它表示对数据的查询。或者如果你想坚持SQL隐喻,它更类似于关系数据库中的VIEW。
由于您正在收听 child_added
您的函数将针对符合您查询的每个用户调用一次。所以 forEach
在你的代码片段中对我来说没有任何意义。如果您想使用 forEach
,您可以使用 value
事件立即获取所有匹配查询的用户:
var searchers = ref.orderByChild("gameSearching").equalTo(true);
searchers.on('value', function(searchersSnapshot) {
searchersSnapshot.forEach(function(snapshot) {
console.log(snapshot.key());
});
});
当前将在您的 Firebase 上记录此内容:
hallo
sam_lous
test2
您 可以 也可以使用 child_added
来完成同样的事情,但在那种情况下您不需要 forEach
:
var searchers = ref.orderByChild("gameSearching").equalTo(true);
searchers.on('child_added', function(snapshot) {
console.log(snapshot.key());
});
有趣的事实:虽然 on('child_added'
会触发缺少索引的 Firebase 警告,但 on('value'
不会。但无论哪种方式:你真的应该添加索引,因为没有那个性能会在你添加玩家时受到无法接受的影响。
因为你指出你只需要一个 child,你还可以进一步限制查询只给你第一个 child:
var searchers = ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1);
的第 2 - 5 节介绍了这些操作和许多其他操作
现在您添加了规则,很清楚那里出了什么问题。
这些是您当前的规则:
{
"rules": {
".read": true,
".write": true,
".indexOn": "gameSearching"
}
}
因此,您允许所有人对整个 Firebase 进行读写访问,并告诉它在 gameSearching
上添加索引。问题是您在顶层定义了索引,而不是在 Firebase 中它需要的级别。
这是您当前的数据结构:
{
"Score" : {
"sam_lous" : {
"score" : 2
}
},
"Users" : {
"hallo" : {
"gameSearching" : true
},
"sam_lous" : {
"gameSearching" : true
},
"test" : {
"gameSearching" : false
},
"test2" : {
"gameSearching" : true
}
}
}
gameSearching
属性 仅存在于 Users
节点的子节点下。所以这就是你应该定义你的 .indexOn
:
的地方
{
"rules": {
".read": true,
".write": true,
"Users": {
".indexOn": "gameSearching"
}
}
}
有了它,您的索引应该被创建(根据我的经验,当您保存规则时它会立即发生)并且 error/warning 消息应该消失。但是要修复该行为,您还应该进行我在其他答案中所做的更改。
我不得不承认 Firebase's documentation on indexing your data 可以更清楚地定义这些 .indexOn
规则。如果 Firebase 的某个人正在阅读,您能否添加一些更好的示例来强调 .indexOn
需要在数据所在的级别定义?
我正在使用 Firebase 检索用户的一些数据。
我需要检索 只有一个用户 与 (gameSearching = true
).
我的数据如下:
Users
|
|_____ John
| |___ name: John Farmer
| |___ gameSearching: true
|
|_____ James
| |___ name: James Smith
| |___ gameSearching: false
|
|_____ Barbara
|___ name: Barbara Smith
|___ gameSearching: true
我正在运行宁此代码:
setData(('Users/' + you + '/'), {gameSearching: true});
var ref = new Firebase("https://grootproject.firebaseio.com/Users");
var child = ref.orderByChild("gameSearching");
child.on("child_added", function (data) {
var yourself = firebase.getAuth().password.email.split("@", 1)[0];
data.forEach(
function (childSnapshot) {
if (childSnapshot[i].val().gameSearching == true && childSnapshot[i].key() != yourself) {
var opponent = childSnapshot[i].key();
setData(('Users/' + opponent + '/'), {gameSearching: false});
setData(('Users/' + yourself + '/'), {gameSearching: false});
}
}
);
});
因为'data'有多个值,所以我用'data.forEach'来分隔。在那之后我可以在 'true' 上设置一个 'return' 这样我只会收到一个 'gameSearching: true'.
的用户我的 firebase 规则:
{
"rules": {
".read": true,
".write": true,
".indexOn": "gameSearching"
}
}
当我 运行 此代码时,出现以下错误:
'Uncaught Error: No index defined for gameSearching'
我搜索过使用“.indexOn”在 'gameSearching' 上设置索引,但没有成功。 https://www.firebase.com/docs/security/guide/indexing-data.html
有人有示例或解决方案吗?
编辑:
我现在得到以下代码:
var ref = new Firebase("https://grootproject.firebaseio.com/Users");
ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1).on("child_added", function (data) {
var yourself = firebase.getAuth().password.email.split("@", 1)[0];
var opponent = data.key();
console.log(opponent);
setData(('Users/' + opponent + '/'), {gameSearching: false});
setData(('Users/' + yourself + '/'), {gameSearching: false});
console.log('ja');
});
我编辑了我的 firebase 规则:
{
"rules": {
".read": true,
".write": true,
"Users": {
".indexOn": "gameSearching"
}
}
}
indexOn 错误不会再显示了,太好了。但是 ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1
) 会 运行s 两次。我不知道这怎么可能。我正在使用 limitToFirst(1)`,所以我期望 1 child?
您的查询对数据进行排序,但未能对其进行筛选。如果将其更改为此,查询将仅匹配正在搜索游戏的用户:
var query = ref.orderByChild("gameSearching").equalTo(true);
这大致转化为 WHERE gameSearching = true
的 SQL,这就是您在上一个问题中提出的问题。请注意,我将变量称为 query
,因为它表示对数据的查询。或者如果你想坚持SQL隐喻,它更类似于关系数据库中的VIEW。
由于您正在收听 child_added
您的函数将针对符合您查询的每个用户调用一次。所以 forEach
在你的代码片段中对我来说没有任何意义。如果您想使用 forEach
,您可以使用 value
事件立即获取所有匹配查询的用户:
var searchers = ref.orderByChild("gameSearching").equalTo(true);
searchers.on('value', function(searchersSnapshot) {
searchersSnapshot.forEach(function(snapshot) {
console.log(snapshot.key());
});
});
当前将在您的 Firebase 上记录此内容:
hallo
sam_lous
test2
您 可以 也可以使用 child_added
来完成同样的事情,但在那种情况下您不需要 forEach
:
var searchers = ref.orderByChild("gameSearching").equalTo(true);
searchers.on('child_added', function(snapshot) {
console.log(snapshot.key());
});
有趣的事实:虽然 on('child_added'
会触发缺少索引的 Firebase 警告,但 on('value'
不会。但无论哪种方式:你真的应该添加索引,因为没有那个性能会在你添加玩家时受到无法接受的影响。
因为你指出你只需要一个 child,你还可以进一步限制查询只给你第一个 child:
var searchers = ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1);
的第 2 - 5 节介绍了这些操作和许多其他操作
现在您添加了规则,很清楚那里出了什么问题。
这些是您当前的规则:
{
"rules": {
".read": true,
".write": true,
".indexOn": "gameSearching"
}
}
因此,您允许所有人对整个 Firebase 进行读写访问,并告诉它在 gameSearching
上添加索引。问题是您在顶层定义了索引,而不是在 Firebase 中它需要的级别。
这是您当前的数据结构:
{
"Score" : {
"sam_lous" : {
"score" : 2
}
},
"Users" : {
"hallo" : {
"gameSearching" : true
},
"sam_lous" : {
"gameSearching" : true
},
"test" : {
"gameSearching" : false
},
"test2" : {
"gameSearching" : true
}
}
}
gameSearching
属性 仅存在于 Users
节点的子节点下。所以这就是你应该定义你的 .indexOn
:
{
"rules": {
".read": true,
".write": true,
"Users": {
".indexOn": "gameSearching"
}
}
}
有了它,您的索引应该被创建(根据我的经验,当您保存规则时它会立即发生)并且 error/warning 消息应该消失。但是要修复该行为,您还应该进行我在其他答案中所做的更改。
我不得不承认 Firebase's documentation on indexing your data 可以更清楚地定义这些 .indexOn
规则。如果 Firebase 的某个人正在阅读,您能否添加一些更好的示例来强调 .indexOn
需要在数据所在的级别定义?