最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Firebase.child failed: First argument was an invalid path - Stack Overflow

programmeradmin1浏览0评论

Possible duplicate. Not sure.

connections: {
      connectionID : {
         userID: true,
         anotherUserID: true
      },

 users: {
   userID : {
       deviceToken : "tokenID",
       name : "Display Name"
   },
   anotherUserID : {
       deviceToken : "tokenID",
       name : "Display Name"
   }
 }

and so on and so forth.

This is my index.js:

exports.sendConnectionNotification = functions.database.ref('/connections/{connectionID}/{userID}').onWrite(event => {

  const parentRef = event.data.ref.parent;
  const userID = event.params.userID;
  const connectionID = event.params.connectionID;

   // If un-follow we exit the function.
  if (!event.data.val()) {
    return console.log('Connection', connectionID, 'was removed.');
  }

  // Get the list of device notification tokens.
  const getDeviceTokensPromise = admin.database().ref('/users/${userID}/deviceToken').once('value');

  // Get the user profile.
  const getUserProfilePromise = admin.auth().getUser(userID);

and it continues. I am getting this error in my logcat:

Error: Firebase.child failed: First argument was an invalid path: "/users/${userID}/deviceToken". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"
    at Error (native)
    at Ge (/user_code/node_modules/firebase-admin/lib/database/database.js:111:59)
    at R.h.n (/user_code/node_modules/firebase-admin/lib/database/database.js:243:178)
    at Fd.h.gf (/user_code/node_modules/firebase-admin/lib/database/database.js:91:631)
    at exports.sendConnectionNotification.functions.database.ref.onWrite.event (/user_code/index.js:31:51)
    at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:35:20
    at process._tickDomainCallback (internal/process/next_tick.js:129:7)

I do not understand why Firebase is not able to reach the node. Clearly, my path is valid. Where am I going wrong? Sorry, I happen to start learning Firebase Functions just today.

**EDIT 1: ** After replacing:

const getDeviceTokensPromise = admin.database().ref('/users/${userID}/deviceToken').once('value');

with

const getDeviceTokensPromise = admin.database().ref(`/users/${userID}/deviceToken`).once('value');

I have gotten a new error. My console log displays:

There are no notification tokens to send to.

Here is my full index.js:

    // // Create and Deploy Your First Cloud Functions


    const functions = require('firebase-functions');
    const admin = require('firebase-admin');
    admin.initializeApp(functions.config().firebase);

    /**
     * Triggers when a user gets a new follower and sends a notification.
     *
     * Followers add a flag to `/followers/{followedUid}/{followerUid}`.
     * Users save their device notification tokens to `/users/{followedUid}/notificationTokens/{notificationToken}`.
     */

    exports.sendConnectionNotification = functions.database.ref('/connections/{connectionID}/{userID}').onWrite(event => {

      const parentRef = event.data.ref.parent;
      const userID = event.params.userID;
      const connectionID = event.params.connectionID;

       // If un-follow we exit the function.
      if (!event.data.val()) {
        return console.log('Connection', connectionID, 'was removed.');
      }

      // Get the list of device notification tokens.
      const getDeviceTokensPromise = admin.database().ref(`/users/${userID}/deviceToken`).once('value');

      // Get the user profile.
      const getUserProfilePromise = admin.auth().getUser(userID);

       return Promise.all([getDeviceTokensPromise, getUserProfilePromise]).then(results => {

        const tokensSnapshot = results[0];
        const user = results[1];

        // Check if there are any device tokens.
        if (!tokensSnapshot.hasChildren()) {
          return console.log('There are no notification tokens to send to.');
        }

        console.log('There are', tokensSnapshot.numChildren(), 'tokens to send notifications to.');
        console.log('Fetched user profile', user);

        // Notification details.
        const payload = {
          notification: {
            title: `${user.userNickName} is here!`,
            body: 'You can now talk to each other.'
          }
        };

        // Listing all tokens.
        const tokens = Object.keys(tokensSnapshot.val());

        // Send notifications to all tokens.
        return admin.messaging().sendToDevice(tokens, payload).then(response => {
          // For each message check if there was an error.
          const tokensToRemove = [];
          response.results.forEach((result, index) => {
            const error = result.error;
            if (error) {
              console.error('Failure sending notification to', tokens[index], error);
              // Cleanup the tokens who are not registered anymore.
              if (error.code === 'messaging/invalid-registration-token' ||
                  error.code === 'messaging/registration-token-not-registered') {
                tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
              }
            }
          });
          return Promise.all(tokensToRemove);
        });
   });
});

Possible duplicate. Not sure.

connections: {
      connectionID : {
         userID: true,
         anotherUserID: true
      },

 users: {
   userID : {
       deviceToken : "tokenID",
       name : "Display Name"
   },
   anotherUserID : {
       deviceToken : "tokenID",
       name : "Display Name"
   }
 }

and so on and so forth.

This is my index.js:

exports.sendConnectionNotification = functions.database.ref('/connections/{connectionID}/{userID}').onWrite(event => {

  const parentRef = event.data.ref.parent;
  const userID = event.params.userID;
  const connectionID = event.params.connectionID;

   // If un-follow we exit the function.
  if (!event.data.val()) {
    return console.log('Connection', connectionID, 'was removed.');
  }

  // Get the list of device notification tokens.
  const getDeviceTokensPromise = admin.database().ref('/users/${userID}/deviceToken').once('value');

  // Get the user profile.
  const getUserProfilePromise = admin.auth().getUser(userID);

and it continues. I am getting this error in my logcat:

Error: Firebase.child failed: First argument was an invalid path: "/users/${userID}/deviceToken". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"
    at Error (native)
    at Ge (/user_code/node_modules/firebase-admin/lib/database/database.js:111:59)
    at R.h.n (/user_code/node_modules/firebase-admin/lib/database/database.js:243:178)
    at Fd.h.gf (/user_code/node_modules/firebase-admin/lib/database/database.js:91:631)
    at exports.sendConnectionNotification.functions.database.ref.onWrite.event (/user_code/index.js:31:51)
    at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:35:20
    at process._tickDomainCallback (internal/process/next_tick.js:129:7)

I do not understand why Firebase is not able to reach the node. Clearly, my path is valid. Where am I going wrong? Sorry, I happen to start learning Firebase Functions just today.

**EDIT 1: ** After replacing:

const getDeviceTokensPromise = admin.database().ref('/users/${userID}/deviceToken').once('value');

with

const getDeviceTokensPromise = admin.database().ref(`/users/${userID}/deviceToken`).once('value');

I have gotten a new error. My console log displays:

There are no notification tokens to send to.

Here is my full index.js:

    // // Create and Deploy Your First Cloud Functions


    const functions = require('firebase-functions');
    const admin = require('firebase-admin');
    admin.initializeApp(functions.config().firebase);

    /**
     * Triggers when a user gets a new follower and sends a notification.
     *
     * Followers add a flag to `/followers/{followedUid}/{followerUid}`.
     * Users save their device notification tokens to `/users/{followedUid}/notificationTokens/{notificationToken}`.
     */

    exports.sendConnectionNotification = functions.database.ref('/connections/{connectionID}/{userID}').onWrite(event => {

      const parentRef = event.data.ref.parent;
      const userID = event.params.userID;
      const connectionID = event.params.connectionID;

       // If un-follow we exit the function.
      if (!event.data.val()) {
        return console.log('Connection', connectionID, 'was removed.');
      }

      // Get the list of device notification tokens.
      const getDeviceTokensPromise = admin.database().ref(`/users/${userID}/deviceToken`).once('value');

      // Get the user profile.
      const getUserProfilePromise = admin.auth().getUser(userID);

       return Promise.all([getDeviceTokensPromise, getUserProfilePromise]).then(results => {

        const tokensSnapshot = results[0];
        const user = results[1];

        // Check if there are any device tokens.
        if (!tokensSnapshot.hasChildren()) {
          return console.log('There are no notification tokens to send to.');
        }

        console.log('There are', tokensSnapshot.numChildren(), 'tokens to send notifications to.');
        console.log('Fetched user profile', user);

        // Notification details.
        const payload = {
          notification: {
            title: `${user.userNickName} is here!`,
            body: 'You can now talk to each other.'
          }
        };

        // Listing all tokens.
        const tokens = Object.keys(tokensSnapshot.val());

        // Send notifications to all tokens.
        return admin.messaging().sendToDevice(tokens, payload).then(response => {
          // For each message check if there was an error.
          const tokensToRemove = [];
          response.results.forEach((result, index) => {
            const error = result.error;
            if (error) {
              console.error('Failure sending notification to', tokens[index], error);
              // Cleanup the tokens who are not registered anymore.
              if (error.code === 'messaging/invalid-registration-token' ||
                  error.code === 'messaging/registration-token-not-registered') {
                tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
              }
            }
          });
          return Promise.all(tokensToRemove);
        });
   });
});
Share Improve this question edited Jun 27, 2017 at 20:23 Aekansh Dixit asked Jun 27, 2017 at 19:52 Aekansh DixitAekansh Dixit 5431 gold badge9 silver badges21 bronze badges 10
  • I am not a firebase guy but is this your actual code with path ('/connections/{connectionID}/{userID}')? just wondering how connectionID and userID are being interpolated with actual values without + or the use of template strings with ` and ${connections.connectionID}/${userID} in between or something like that. From your snippet, I just see the path is just that plain string '/connections/{connectionID}/{userID}' – Juan Commented Jun 27, 2017 at 20:00
  • Well. I'm a newbie. Took this for reference: github./firebase/functions-samples/blob/master/… – Aekansh Dixit Commented Jun 27, 2017 at 20:03
  • 1 ohh ok! :D try to set the path with its desired values with + or ` . For example '/connections/' + connections.connectionID + '/' + connections.connectionID.userID This way that string has the actual object values. Or with ` (template literals), read here on these developer.mozilla/en-US/docs/Web/JavaScript/Reference/…. Then ment back if you get a different error. The userID: true doesn't make much sense but I figure it must be just an example. – Juan Commented Jun 27, 2017 at 20:07
  • I think this is your issue. From the error you post, '/users/${userID}/deviceToken' is plaining about $, definitively not being interpolated as you didn't use ` , interpolation doesn't work with '. Keep us posted :) – Juan Commented Jun 27, 2017 at 20:11
  • I see, look in that reference this line: github./firebase/functions-samples/blob/master/… It uses `, slightly different to '. Easily confused. So from what I see there, keep the original first path as is, and modify that one that calls .value(). – Juan Commented Jun 27, 2017 at 20:17
 |  Show 5 more ments

3 Answers 3

Reset to default 2

You can do use (`) instead of (') as i was also having same problem and solved by using this. thanks

Change

const getDeviceTokensPromise = admin.database().ref('/users/${userID}/deviceToken').once('value');

to

const getDeviceTokensPromise = admin.database().ref('/users/' + userID + '${userID}/deviceToken').once('value');

'/users/${userID}/deviceToken' is not a valid path. but '/users/123456/deviceToken' where 123456 represents the user ID, is.

maybe you are using single quote instead of back-ticks. https://developers.google./web/updates/2015/01/ES6-Template-Strings

so the path is not concatenated in a right way.

发布评论

评论列表(0)

  1. 暂无评论