3
votes

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" : "[email protected]",
      "userId" : "1vWvSXDQITMmKdUIY7SYoLA1MgU2",
      "userName" : "Malik Abdul Kawee",
      "userPhoneNumber" : "",
      "userProfileImage" : "https://pbs.twimg.com/profile_images/1018741325875867648/ZnKeUiOJ_400x400.jpg"
    },
    "YJdwgRO08nOmC5HdEokr1NqcATx1" : {
      "following" : {
        "1vWvSXDQITMmKdUIY7SYoLA1MgU2" : {
          "currentFollowingUserId" : "YJdwgRO08nOmC5HdEokr1NqcATx1",
          "userEmail" : "[email protected]",
          "userId" : "1vWvSXDQITMmKdUIY7SYoLA1MgU2",
          "userName" : "Malik Abdul Kawee",
          "userPhoneNumber" : "",
          "userProfileImage" : "https://pbs.twimg.com/profile_images/1018741325875867648/ZnKeUiOJ_400x400.jpg"
        }
      },
      "userEmail" : "[email protected]",
      "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
The error message has a trailing users at the end, which is missing in your JSON and rules. It seems like you're querying data that doesn't exist. - Frank van Puffelen
@FrankvanPuffelen I think problem is with this line return snap.ref.parent.child('users') after getting data from following node I'm trying to get its parent node and I dnt know how to get parent parent node so , I just tried using snap.ref.parent . - Atif AbbAsi
snap.ref.parent.parent? Although I think you might be looking for snap.ref.root. See the reference docs for all properties of a DatabaseReference: firebase.google.com/docs/reference/admin/node/… - Frank van Puffelen
Thanks @FrankvanPuffelen snap.ref.parent.parent.parent worked for me. - Atif AbbAsi

1 Answers

1
votes

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').