Reputation: 2148
I am trying to send a notification to "PLAYER 2" when a new game is added. Here is my code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNewGameNotification= functions.database.ref('/GAMES/{gameId}/PLAYER 2').onWrite(event => {
const player2uid = event.params.val;
const getDeviceTokensPromise = admin.database().ref(`/USERS/${player2uid}/fcm`).once('value');
return Promise.all([getDeviceTokensPromise]).then(results => {
const tokensSnapshot = results[0];
// Notification details.
const payload = {
'data': {
'title': "Tienes una nueva partida"
}
};
// Listing all tokens, error here below.
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);
});
});
});
When it is executed, in the firebase console says
TypeError: Cannot convert undefined or null to object
Like if it were null but the fcm is there, what am i doing wrong?
Upvotes: 1
Views: 1969
Reputation: 38319
I think instead of this:
const player2uid = event.params.val;
you want this:
const player2uid = event.data.val();
Edit:
This update to your code contains some added checks and a simplification. This works for me.
The database structure for storing the token (or tokens) is critical. The tokens are the keys, not the values. The values are not significant and can be simple placeholders, such as booleans.
For example:
"USERS" : {
"Roberto" : {
"fcm" : {
"eBUDkvnsvtA:APA...rKe4T8n" : true
}
},
"Juan" : {
"fcm" : {
"fTY4wvnsvtA:APA91bGZMtLY6R...09yTLHdP-OqaxMA" : true
}
}
}
.
exports.sendNewGameNotification= functions.database.ref('/GAMES/{gameId}/PLAYER 2').onWrite(event => {
const player2uid = event.data.val();
return admin.database().ref(`/USERS/${player2uid}`).once('value').then(snapshot => {
if (!snapshot.exists()) {
console.log('Player not found:', player2uid);
return;
}
const tokensSnapshot = snapshot.child('fcm');
if (!tokensSnapshot.exists()) {
console.log('No tokens for player: ', player2uid);
return;
}
// Notification details.
const payload = {
'data': {
'title': "Tienes una nueva partida"
}
};
// Listing all tokens, error here below.
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);
});
});
});
Upvotes: 3