In an android app, I am using FCM for sending notifications, the cloud function executed successfully, as shown in the firebase console log, but in my device its not showing any notification, what could be the reason ?
Below is the code for my index.js
let functions = require('firebase-functions');
let admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/notifications/messages/{pushId}')
.onWrite(event => {
console.log('notifying start1');
const message = event.data.current.val();
const senderUid = message.from;
const receiverUid = message.to;
console.log('SenderId '+senderUid + ' Receiver Id '+receiverUid);
const promises = [];
console.log('notifying start2');
if (senderUid == receiverUid) {
//if sender is receiver, don't send notification
promises.push(event.data.current.ref.remove());
return Promise.all(promises);
}
console.log('notifying start3');
const getInstanceIdPromise = admin.database().ref(`/users/${receiverUid}/accessToken`).once('value');
console.log('notifying start4');
const getReceiverUidPromise = admin.auth().getUser(receiverUid);
console.log('notifying start5');
return Promise.all([getInstanceIdPromise, getReceiverUidPromise]).then(results => {
const accessToken = results[0].val();
const receiver = results[1];
console.log('notifying ' + receiverUid + ' about ' + message.body + ' from ' + senderUid);
const payload = {
notification: {
title: 'Firebase Notification',
body: message.body,
}
};
admin.messaging().sendToDevice(accessToken, payload)
.then(function (response) {
console.log("Successfully sent message:", response);
})
.catch(function (error) {
console.log("Error sending message:", error);
});
});
});
Kindly help! Thanks in advance.
Had the same problem and couldn't understand what was wrong since the error details were not shown i.e. { error: [Object] }
Successfully sent message: { results: [ { error: [Object] } ],
canonicalRegistrationTokenCount: 0,
failureCount: 1,
successCount: 0,
multicastId: 5487635521698134000
}
So changed/added a log in the cloud function code to access the error details i.e. console.log(response.results[0].error);.
code (in the cloud function):
admin.messaging().sendToDevice(registrationToken, payload)
.then(function(response) {
console.log("Successfully sent message:", response);
console.log(response.results[0].error);
})
.catch(function(error) {
console.log("Error sending message:", error);
});
error details:
{ Error: The provided registration token is not registered. A previously valid registration token can be unregistered for a variety of reasons. See the error documentation for more details. Remove this registration token and stop using it to send messages.
at FirebaseMessagingError.Error (native)
at FirebaseMessagingError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:25:28)
at new FirebaseMessagingError (/user_code/node_modules/firebase-admin/lib/utils/error.js:130:23)
at Function.FirebaseMessagingError.fromServerError (/user_code/node_modules/firebase-admin/lib/utils/error.js:154:16)
at /user_code/node_modules/firebase-admin/lib/messaging/messaging.js:80:63
at Array.forEach (native)
at mapRawResponseToDevicesResponse (/user_code/node_modules/firebase-admin/lib/messaging/messaging.js:76:26)
at /user_code/node_modules/firebase-admin/lib/messaging/messaging.js:223:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
errorInfo:
{ code: 'messaging/registration-token-not-registered',
message: 'The provided registration token is not registered. A previously valid registration token can be unregistered for a variety of reasons. See the error documentation for more details. Remove this registration token and stop using it to send messages.' } }
Not sure if you have the same error I do...
Related
My application is simply order app and I want admin get notification when new order is placed.
So to do that I send notification to device with token Id by using firebase functions.
'use-strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('admin/{user_id}/notification/{notification_id}').onCreate((snapshot, context) => {
console.log("hehehehehehehehe");
const user_id=context.params.user_id;
const getDeviceTokensPromise = admin.database().ref(`admin/${user_id}`).once('value');
//let tokensSnapshot;
//let tokes;
return Promise.all([getDeviceTokensPromise]).then(result => {
//const registrationToken= result[0].tokenid.val();
//console.log(registrationToken);
const payload = {
notification: {
title: 'You have a new follower!',
body: 'Yeni sifaris var',
}
};
return admin.messaging().sendToDevice('fOCU86Rhhb4:APA91bHwJZInZYGp9cIDc7PyCw48QcEvvMOMuFepYcCTvkxlCJp8_Ieq1Ikwd9xNoU2rfTA9paRqCTLAuhUlZgF952AvpBstGdGRWMK8lCR2MHgHn6xzbvyxFEu-auRYexnPYmOnlTB1',payload).then((response) => {
return console.log('Successfully sent message:', response);
}).catch((error) => {
return console.log('Error sending message:', error);
});
});
});
Although I got the success response message in console log, my android phone couldn't get any notification.
Successfully sent message: { results: [ { messageId: '0:1542910779596746%095eb9af095eb9af' } ],
canonicalRegistrationTokenCount: 0,
failureCount: 0,
successCount: 1,
multicastId: 6551370257673400000 }
What is wrong with my code. I am new to firebase. I need your help.
i am getting warnings in firebase cloud functions log. the functions were deployed properly and was working before. now i am getting an error.
#firebase/database: FIREBASE WARNING: Provided authentication credentials for the app named "[DEFAULT]" are invalid. This usually indicates your app was not initialized correctly. Make sure the "credential" property provided to initializeApp() is authorized to access the specified "databaseURL" and is from the correct project.
I have spent 5 to 6 hours for searching solution then i tried one solution in which i have downloaded the the serviceAccountKey.json file and use that file but the i got an other error while deploying the functions. and i didn't find any solution yet.
here is the error
Error: Error occurred while parsing your function triggers.
ReferenceError: functions is not defined
at Object.<anonymous> (D:\Parental Sheild\Coding\defenderFunctions\functions\index.js:22:25)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at C:\Users\H.A.R\AppData\Roaming\npm\node_modules\firebase-tools\lib\triggerParser.js:18:11
at Object.<anonymous> (C:\Users\H.A.R\AppData\Roaming\npm\node_modules\firebase-tools\lib\triggerParser.js:38:3)
i have upgrade node to 8.12.0 and upgrade npm to latest version.
here the code of initializing App
const functions = require('firebase-functions');
const admin = require("firebase-admin");
const serviceAccount = require("./serviceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://database url"
});
here is my firebase function code
exports.sendMessage = functions.database.ref('/Defender/{UserId}/Child/{PinId}/Messages/{pushId}')
.onWrite((change,context) => {
const message = change.after.val();
const sender = message.from;
const receiver = message.to;
const userID= message.uid;
const promises = [];
// if (senderUid == receiverUid) {
// //if sender is receiver, don't send notification
// promises.push(change.after.ref.remove());
// return Promise.all(promises);
// }
if (userID== receiver) {
const getInstanceIdPromise = admin.database().ref(`/Defender/${userID}/Profile/instanceId`).once('value');
const getSenderUidPromise = admin.database().ref(`/Defender/${userID}/Child/${sender}/Profile/name`).once('value');
return Promise.all([getInstanceIdPromise, getSenderUidPromise]).then(results => {
const instanceId = results[0].val();
const sender = results[1].val();
console.log('notifying ' + receiver + ' about ' + message.body + ' from ' + sender);
const payload = {
notification: {
title: sender,
body: message.body,
sound: "default"
// icon: sender.photoURL
}
};
admin.messaging().sendToDevice(instanceId, payload)
.then(function (response) {
console.log("Successfully sent message:", response);
})
.catch(function (error) {
console.log("Error sending message:", error);
});
});
}else{
const getInstanceIdPromise = admin.database().ref(`/Defender/${userID}/Child/${receiver}/Profile/instanceId`).once('value');
const getSenderUidPromise = admin.database().ref(`/Defender/${userID}/Profile/displayName`).once('value');
return Promise.all([getInstanceIdPromise, getSenderUidPromise]).then(results => {
const instanceId = results[0].val();
const sender = results[1].val();
console.log('notifying ' + receiver + ' about ' + message.body + ' from ' + sender);
const payload = {
notification: {
title: sender,
body: message.body,
sound: "default"
// icon: sender.photoURL
}
};
admin.messaging().sendToDevice(instanceId, payload)
.then(function (response) {
console.log("Successfully sent message:", response);
})
.catch(function (error) {
console.log("Error sending message:", error);
});
});
}
});
Update: i have found the issue. i am reading data from database inside the function and getting error because i have secure rules on my firebase database. now i don't know how to solve this issue. any help?
You're using functions, but you never apparently never defined it in your code. You probably meant to require the firebase-functions at the top of your code:
const functions = require('firebase-functions')
I am developing an Android application in which I have an Activity, OperatorActivity. It have CardNo and LineNo as EditText and that values are inserted to FirebaseDatabase.
What I want to do is to notify every user who have this App installed of the Update using FCM. I used Note.js and created a function for this but everytime there is an error:
TypeError: admin.messaging.sendToTopic is not a function
at exports.sendNotification.functions.database.ref.onWrite.event (/user_code/index.js:18:21)
at cloudFunctionNewSignature (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:105:23)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:135:20)
at /var/tmp/worker/worker.js:733:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
I am new to Functions so I can't understand how I solve this error.
I have already looked similar questions but none solved my problem.
index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config.firebase);
exports.sendNotification = functions.database.ref("Operator :")
.onWrite(event =>{
var payload = {
notification :{
title : 'Mechanic Needed',
body: 'Any available mechanic report ASAP',
sound: 'defaulf',
badge: '1'
},
topic: 'notification'
};
admin.messaging.sendToTopic('notification',payload)
.then(function(response){
console.log("Successfully sent Message.", response);
return;
})
.catch(function(error){
console.log("Error sending message!", erorr);
})
});
I subscribed all the users to 'notification' topic programmatically.
This is how database looks :
This is a Dummy database.
firebase --version : 4.2.1
npm --version : 6.4.1
EDIT :
This is working now.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config.firebase);
exports.sendNotificationToUsers = functions.database.ref("Operator :")
.onWrite(event =>{
var payload = {
notification: {
title : 'Mechanic Needed',
body: 'Any available mechanic report ASAP',
sound: 'defaulf'
}
};
admin.messaging().sendToTopic('notification',payload)
.then((response) => {
console.log("Successfully sent Message.", response);
return;
})
.catch((error) => {
console.log("Error sending message!", error);
})
});
Instead of this:
admin.messaging
You need to use this (note from the API docs that it's a function to call):
admin.messaging()
See also the documentation for sending to a topic.. It shows the same usage.
Below code is my firebase function index.js file
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref("Notifications/{userId}")
.onWrite(event => {
var request = event.data.val();
var payload = {
data: {
title: "Welcome to ChitChat Group",
message: "You may have new messages"
}
};
admin.messaging().sendToDevice(request.token, payload)
.then(function (response) {
console.log("Successfully sent message: ", response);
})
.catch(function (error) {
console.log("Error sending message: ", error);
})
});
below code contains where i crate token when user get registered
String uid = (String) firebaseAuth.getCurrentUser().getUid();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Notifications/"+uid);
reference.child("token").setValue(FirebaseInstanceId.getInstance().getToken());
You can make all your users subscribe to one big topic like registration on newMembers then send notification to the topic :
var message = {
to: '/topics/newMembers',
notification: {
title: 'title',
body: 'body'
},
};
I am trying to make a cloud function that sends a push notification to a given user.
The user makes some changes and the data is added/updated under a node in firebase database (The node represents an user id). Here i want to trigger a function that sends a push notification to the user.
I have the following structure for the users in DB.
Users
- UID
- - email
- - token
- UID
- - email
- - token
Until now i have this function:
exports.sendNewTripNotification = functions.database.ref('/{uid}/shared_trips/').onWrite(event=>{
const uuid = event.params.uid;
console.log('User to send notification', uuid);
var ref = admin.database().ref('Users/{uuid}');
ref.on("value", function(snapshot){
console.log("Val = " + snapshot.val());
},
function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
When i get the callback, the snapshot.val() returns null. Any idea how to solve this? And maybe how to send the push notification afterwards?
I managed to make this work. Here is the code that sends a notification using Cloud Functions that worked for me.
exports.sendNewTripNotification = functions.database.ref('/{uid}/shared_trips/').onWrite(event=>{
const uuid = event.params.uid;
console.log('User to send notification', uuid);
var ref = admin.database().ref(`Users/${uuid}/token`);
return ref.once("value", function(snapshot){
const payload = {
notification: {
title: 'You have been invited to a trip.',
body: 'Tap here to check it out!'
}
};
admin.messaging().sendToDevice(snapshot.val(), payload)
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
})
Just answering the question from Jerin A Mathews...
Send message using Topics:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
//Now we're going to create a function that listens to when a 'Notifications' node changes and send a notificcation
//to all devices subscribed to a topic
exports.sendNotification = functions.database.ref("Notifications/{uid}")
.onWrite(event => {
//This will be the notification model that we push to firebase
var request = event.data.val();
var payload = {
data:{
username: request.username,
imageUrl: request.imageUrl,
email: request.email,
uid: request.uid,
text: request.text
}
};
//The topic variable can be anything from a username, to a uid
//I find this approach much better than using the refresh token
//as you can subscribe to someone's phone number, username, or some other unique identifier
//to communicate between
//Now let's move onto the code, but before that, let's push this to firebase
admin.messaging().sendToTopic(request.topic, payload)
.then((response) => {
console.log("Successfully sent message: ", response);
return true;
})
.catch((error) => {
console.log("Error sending message: ", error);
return false;
})
})
//And this is it for building notifications to multiple devices from or to one.
Return this function call.
return ref.on("value", function(snapshot){
console.log("Val = " + snapshot.val());
},
function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
This will keep the cloud function alive until the request is complete. Learn more about returning promises form the link give by Doug in the comment.
Send Notification for a Topic In Cloud function
Topics a basically groups you can send notification for the selected group
var topic = 'NOTIFICATION_TOPIC';
const payload = {
notification: {
title: 'Send through Topic',
body: 'Tap here to check it out!'
}
};
admin.messaging().sendToTopic(topic,payload);
You can register the device for any new or existing topic from mobile side
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotificationToTopic =
functions.firestore.document('Users/{uuid}').onWrite(async (event) => {
//let title = event.after.get('item_name');
//let content = event.after.get('cust_name');
var message = {
notification: {
title: "TGC - New Order Recieved",
body: "A New Order Recieved on TGC App",
},
topic: 'orders_comming',
};
let response = await admin.messaging().send(message);
console.log(response);
});
For sending notifications to a topic, The above code works well for me, if you have any doubt, let me know.