Reputation: 1032
I'm trying to get push notifications to work using this tutorial: https://www.youtube.com/watch?v=z27IroVNFLI
It's obviously a bit old, but there aren't many good alternatives for Firebase web apps.
I'm getting the following error when my cloud function runs:
fcmSend
Error: Reference.child failed: First argument was an invalid path = "/fcmTokens/[object Object]". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]" at validatePathString (/srv/node_modules/@firebase/database/dist/index.node.cjs.js:1636:15) at validateRootPathString (/srv/node_modules/@firebase/database/dist/index.node.cjs.js:1647:5) at Reference.child (/srv/node_modules/@firebase/database/dist/index.node.cjs.js:13688:17) at Database.ref (/srv/node_modules/@firebase/database/dist/index.node.cjs.js:14862:48) at exports.fcmSend.functions.database.ref.onWrite (/srv/index.js:21:12) at cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:131:23) at /worker/worker.js:825:24 at at process._tickDomainCallback (internal/process/next_tick.js:229:7)
Here's by cloud function:
exports.fcmSend = functions.database
.ref('/model_outputs/real_estate')
.onWrite((change, context) => {
const userId = change.after.val();
console.log(change);
const payload = {
notification: {
title: "test",
body: "test body",
icon: "https://placeimg.com/250/250/people"
}
};
admin.database()
.ref(`/fcmTokens/${userId}`)
.once('value')
.then(token => token.val() )
.then(userFcmToken => {
return admin.messaging().sendToDevice(userFcmToken, payload)
})
.then(res => {
console.log("Sent Successfully", res);
return null;
})
.catch(err => {
console.log(err);
});
});
I've seen other people post about this error, but most of them had to do when them using 's instead of s in this case:
admin.database().ref(/fcmTokens/${userId}
)`. As you can see, I'm using ticks, so I'm not sure what's wrong here.
Here's how the data is structured in my db:
Obviously, I chopped off the ID, but I just wanted to illustrate that it's nested immediately under /fcmTokens
.
Upvotes: 0
Views: 444
Reputation: 83191
It seems that there are several problems in your Cloud Function:
The following line generates an error because userId
is not a String.
admin.database().ref(`/fcmTokens/${userId}`)
Most probably the value of the DB node at '/model_outputs/real_estate'
is an Object and therefore when you do const userId = change.after.val();
you assign an Object to userId
Update following your comment above: It seems you get undefined
for userId
. You need to debug and solve this problem: it has to be a string.
The following promise chaining is wrong:
admin.database()
.ref(`/fcmTokens/${userId}`)
.once('value')
.then(token => token.val() ) // You don't return anything here, and not a Promise
.then(userFcmToken => {
return admin.messaging().sendToDevice(userFcmToken, payload)
})
.then(res => {
console.log("Sent Successfully", res);
return null;
})
.catch(err => {
console.log(err);
});
It should be something along the following lines, if I correctly understand your logic and data model:
admin.database()
.ref(`/fcmTokens/${userId}`)
.once('value')
.then(snapshot => {
const userFcmToken = snapshot.val();
return admin.messaging().sendToDevice(userFcmToken, payload)
})
.then(res => {
console.log("Sent Successfully", res);
return null;
})
.catch(err => {
console.log(err);
});
Upvotes: 2