Firebase.child失败:第一个参数是无效路径

时间:2017-06-27 19:52:13

标签: javascript android firebase firebase-realtime-database firebase-cloud-messaging

可能重复。不确定。

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

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

依此类推。

这是我的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);

然后继续。我在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)

我不明白为什么Firebase无法访问该节点。显然,我的路径是有效的。我哪里错了?对不起,我刚刚开始学习Firebase功能。

**编辑1:** 更换后:

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

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

我收到了一个新错误。我的控制台日志显示:

There are no notification tokens to send to.

这是我的完整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);
        });
   });
});

3 个答案:

答案 0 :(得分:2)

你可以使用(`)而不是('),因为我也有同样的问题,并通过使用它解决。 感谢

答案 1 :(得分:0)

更改

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

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

'/users/${userID}/deviceToken'不是有效路径。 但是'/users/123456/deviceToken' 123456代表用户ID,是。

答案 2 :(得分:0)

也许你正在使用单引号而不是后退。 https://developers.google.com/web/updates/2015/01/ES6-Template-Strings

所以路径没有以正确的方式连接。