Reputation: 1097
I have written a firebase function to send notification whenever a like occurs in my android app. The notification functionality works good most of the times but sometimes does not work.
I receive this error always ( whether it is working or not):
Function returned undefined, expected Promise or value
Here's the code of my like function:
exports.sendactorLikeNotification = functions.database.ref('/Likes/{post_id}/{user_id}')
.onWrite(event => {
if (event.data.exists())
{
const message = event.data.val();
const userUid = event.params.user_id;
const ownerUid = message.owner_id;
console.log("Owner id", ownerUid);
const userPic = message.thumb_image;
const userName = message.name;
const post_key = event.params.post_id;
const timestamp = admin.database.ServerValue.TIMESTAMP;
if(ownerUid == userUid){return null;}
const Promise1= admin.database().ref(`/notifs/${ownerUid}`).push({
thumb_image: userPic,
name: userName,
user_id: userUid,
post_id: post_key,
text: "liked your post",
type: "Like",
read: "false",
time: timestamp
});
const Promise2=admin.database().ref(`/Users/${ownerUid}/device_token`).once('value');
const Promise3= Promise2.then(function(snapshot) {
const getrealDeviceTokensPromise = snapshot.val();
console.log("Device Token", getrealDeviceTokensPromise);
// Notification details.
const payload = {
notification: {
title: 'Appname',
body: userName + ' has liked your post.',
icon: "default",
sound: "default",
click_action: "OPEN_ACTIVITY_1"
}
};
const Promise4= admin.messaging().sendToDevice(getrealDeviceTokensPromise, payload)
.then(function (response) {
console.log("Successfully sent message:", response);
return Promise.all([Promise1,Promise3,Promise4]);
})
.catch(function (error) {
console.log("Error sending message:", error);
return null;
});
}, function(error) {
// The Promise was rejected.
console.error(error);
return null;
});
}
else
{
return null;
}
});
I don't understand where I am going wrong. Please help!
Upvotes: 4
Views: 5394
Reputation: 1097
exports.sendactorLikeNotification = functions.database.ref('/Likes/{post_id}/{user_id}').onWrite(event => {
if (event.data.exists()) {
const promises=[];
const message = event.data.val();
const userUid = event.params.user_id;
const ownerUid = message.owner_id;
console.log("Owner id", ownerUid);
const userPic = message.thumb_image;
const userName = message.name;
const post_key = event.params.post_id;
const timestamp = admin.database.ServerValue.TIMESTAMP;
if(ownerUid == userUid){return null;}
const a1=admin.database().ref(`/notifs/${ownerUid}`).push({
thumb_image: userPic,
name: userName,
user_id: userUid,
post_id: post_key,
text: "liked your post",
type: "Like",
read: "false",
time: timestamp
});
promises.push(a1);
const a2= admin.database().ref(`/Users/${ownerUid}/device_token`).once('value').then(function(snapshot) {
const getrealDeviceTokensPromise = snapshot.val();
console.log("Device Token", getrealDeviceTokensPromise);
// Notification details.
const payload = {
notification: {
title: 'Appname',
body: userName + ' has liked your post.',
icon: "default",
sound: "default",
click_action: "OPEN_ACTIVITY_1"
}
};
const a3=admin.messaging().sendToDevice(getrealDeviceTokensPromise, payload)
.then(function (response) {
console.log("Successfully sent message:", response);
})
.catch(function (error) {
console.log("Error sending message:", error);
});
promises.push(a3);
}, function(error) {
console.error(error);
});
promises.push(a1);
return Promise.all(promises);
}
else
{
return null;
}
});
This code solved the problem for me!
Upvotes: 2
Reputation: 1758
Please test the following changes and let me know, also I recommend updating the firebase-functions SDK:
exports.sendactorLikeNotification = functions.database.ref('/Likes/{post_id}/{user_id}')
.onWrite(event => {
if (event.data.exists()) {
const promises = [];
const message = event.data.val();
const userUid = event.params.user_id;
const ownerUid = message.owner_id;
const userPic = message.thumb_image;
const userName = message.name;
const post_key = event.params.post_id;
const timestamp = admin.database.ServerValue.TIMESTAMP;
if (ownerUid === userUid) return null;
return Promise.all([admin.database().ref(`/Users/${ownerUid}/device_token`).once('value')]).then(r => {
const cO = r[0];
const aP = admin.database().ref(`/notifs/${ownerUid}`).push({
thumb_image: userPic,
name: userName,
user_id: userUid,
post_id: post_key,
text: "liked your post",
type: "Like",
read: "false",
time: timestamp
});
promises.push(aP);
const payload = {
notification: {
title: 'Appname',
body: userName + ' has liked your post.',
icon: "default",
sound: "default",
click_action: "OPEN_ACTIVITY_1"
}
};
const tokensList = Object.keys(cO.val());
promises.push(admin.messaging().sendToDevice(tokensList, payload));
return Promise.all(promises);
});
}
return null;
});
Upvotes: 0
Reputation: 317467
You're returning undefined when:
event.data.exists()
returns falseownerUid == userUid
You're also not dealing with the promise returned by sendToDevice().then().catch()
. The function needs to wait until that work is done before terminating.
Upvotes: 1