问题
I'm using fire-base to retrieve nested data of users node, and while running query I'm facing this issue fetching data from fire-base database.
Consider adding ".indexOn": "userId" at /users/YJdwgRO08nOmC5HdEokr1NqcATx1/following/users to your security rules for better performance.
Database Structure:
"users" : {
"1vWvSXDQITMmKdUIY7SYoLA1MgU2" : {
"userEmail" : "test2kawee@gmail.com",
"userId" : "1vWvSXDQITMmKdUIY7SYoLA1MgU2",
"userName" : "Malik Abdul Kawee",
"userPhoneNumber" : "",
"userProfileImage" : "https://pbs.twimg.com/profile_images/1018741325875867648/ZnKeUiOJ_400x400.jpg"
},
"YJdwgRO08nOmC5HdEokr1NqcATx1" : {
"following" : {
"1vWvSXDQITMmKdUIY7SYoLA1MgU2" : {
"currentFollowingUserId" : "YJdwgRO08nOmC5HdEokr1NqcATx1",
"userEmail" : "test2kawee@gmail.com",
"userId" : "1vWvSXDQITMmKdUIY7SYoLA1MgU2",
"userName" : "Malik Abdul Kawee",
"userPhoneNumber" : "",
"userProfileImage" : "https://pbs.twimg.com/profile_images/1018741325875867648/ZnKeUiOJ_400x400.jpg"
}
},
"userEmail" : "test2atif@gmail.com",
"userId" : "YJdwgRO08nOmC5HdEokr1NqcATx1",
"userName" : "Atif AbbAsi",
"userPassword" : "test123",
"userPhoneNumber" : "",
"userProfileImage" : "http://paperlief.com/images/enrique-iglesias-body-workout-wallpaper-4.jpg"
}
}
Database Rules:
"users": {
".indexOn": ["userId","currentFollowingUserId",".value"],
"$userId": {
"following": {
//"$userId": {
".indexOn": ["userId","currentFollowingUserId",".value"]
}
//}
}
}
Function Query:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendFollowingNotifications = functions.database.ref('/users/{userId}/following/{followingId}')
//.onWrite(event => {
.onCreate((snap,context) => {
console.info("Child value is val() " ,snap);
var childNodeValue=snap.val();
var topic=childNodeValue.userId;
//var ref = firebase.database().ref.child('users');
//console.log("testing ref pathName : " ,snap.ref.parent.parent.parent.pathname);
// console.log("testing ref : " ,snap.ref.parent.parent.parent.path);
//var ref = admin.database().ref("users");
//.child('users')
return snap.ref.parent.parent.parent.orderByChild("userId").equalTo(childNodeValue.currentFollowingUserId)
// .on('child_changed').then(snapshot => { once('value')
.once('value', function(snapshot){
var parentNodeValue=snapshot.val();
console.info("Topic ID " ,topic);
console.info("Parent value is val() " ,snapshot.val());
var payload = {
data: {
username: parentNodeValue.userName,
imageurl:parentNodeValue.userProfileImage,
description:"Started Following You"
}
};
// Send a message to devices subscribed to the provided topic.
return admin.messaging().sendToTopic(topic, payload)
.then(function (response) {
// See the MessagingTopicResponse reference documentation for the
// contents of response.
console.log("Successfully sent message:", response);
return response;
})
.catch(function (error) {
console.log("Error sending message:", error);
return error;
});
});
});
return snap.ref.parent.child('users').orderByChild("userId").equalTo(childNodeValue.currentFollowingUserId)
I think the problem is with this query , My first query on following node is returning me data but when I'm retrieving data of its parent node user, I'm getting warning.
I tried to use functions.database.ref but it gave me below exception.
so I tried using this `snap.ref.parent.`to get reference of parent node.
Firebase Functions, admin.database().ref(…) is not a function
Firebase Functions, functions.database().ref(…) is not a function
回答1:
You are getting the wrong reference for reading the user. You need to do the following to get correct reference: snap.ref.parent.parent.parent (ref now will be at /users). You query is trying to read the users node under following.
The warning is that you need to write the firebase rule which enables the indexing based on userId, otherwise the operation will be bandwidth expensive.
here is the rule which will add indexing:
"users": {
"$uid" : {
".indexOn" : ["userId"]
}
}
Here is the resource for more information on Database rules : https://firebase.google.com/docs/database/security/
This is a simple tool by firebase to write rules easily: https://github.com/firebase/bolt
P.S: you are returning two promises your last promise for sending notification will not work. Nest or chain it with the firebase query. Also make your query single value event with changing on('child_changed') to once('value').
来源:https://stackoverflow.com/questions/51853852/unspecified-index-when-searching-data-with-firebase-cloud-function-on-nested-obj