Cloud Functions for Firebase ( No Log Messages) - android

This is my first time using Cloud Functions for Firebase and Node.js, so
I have no idea why I can't see any logs on my Firebase console.
At least, I've successfully deployed the function below
'use strict';
const functions = require('firebase-functions');
//import admin module
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
/* Listens for new messages added to events and sends a notification to
subscribed users */
exports.pushNotification =
functions.database.ref('/events/{pushId}').onWrite( event => {
console.log('Push notification event triggered');
/* Grab the current value of what was written to the Realtime Database
*/
var valueObject = event.data.val();
/* Create a notification and data payload. They contain the
notification information, and message to be sent respectively */
const payload = {
data: {
eventType: valueObject.eventType,
receiver: valueObject.receiver,
requester: valueObject.requester
}
};
/* Create an options object that contains the time to live for the
notification and the priority. */
const options = {
priority: "high",
timeToLive: 60 * 60 * 24 //24 hours
};
return admin.messaging().sendToTopic(valueObject.receiver, payload,
options).then(function (response) {
console.log("Successfully sent message:", response);
})
.catch(function (error) {
console.log("Error sending message:", error);
});
});
However, I couldn't see any log messages on Firebase Console even if I write some data to my 'events' database.
Does it mean this function wasn't triggered at all?
I would really appreciate if someone could suggest the cause of this issue.

If you've set up your application correctly in the console, then there's no reason why logging would not happen if the function is fired.
That leaves you with the possibility that the function is not being fired up. A possible reason for that is that the data is not being written at the path provided in your function.
So, are you adding a value to /events such as 'true' or 'ABC', or are you adding a child to it such as {'ABC' = true}?
In the case of .ref(/events/{pushId}), the function will be called in the latter case and not the former.

Related

Is there a way to send notifications by identifying user rather than device?

In my android application, I want to send notifications for text messages send from one user to another and I've deployed this Node.js function into firebase functions:
'use strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref(`/notification/{receiver_user_id}/{notification_id}`)
.onWrite((data, context) =>
{
const receiver_user_id = context.params.receiver_user_id;
const notification_id = context.params.notification_id;
console.log('We have a notification to send to :' , receiver_user_id);
if (!data.after.val())
{
console.log('A notification has been deleted :' , notification_id);
return null;
}
const DeviceToken = admin.database().ref(`/users/${receiver_user_id}/user_id`).once('value');
return DeviceToken.then(result =>
{
const token_id = result.val();
console.log("Token Id ", token_id);
const payload =
{
notification:
{
title: "New Mesaage",
body: `you have a new Message, Please Check.`,
icon: "default"
}
};
console.log("This is payload ", payload);
return admin.messaging().sendToDevice(token_id, payload).then()
.catch(function (error)
{
console.log("Error sending message: ", error); // here no return
});
});
});
I think the problem lies with sendToDevice() method as I'm not getting any notification and I don't want to send by device_token.
I want to send notifications to the device in which the user with a particular "user_id" is logged in
This is my database model
This is the log I got:
and I don't want to send by device_token
If you want to target a message to a particular user's device, you must use a device token. That's the way it works.
FCM doesn't know anything about the individual users of your app. FCM just knows about individual devices whose tokens you collect in the app and send to your backend (or store in your database). You have to associate the token to the user account somehow. You should also assume that one user might be using multiple devices.
What you should probably do first is start collecting the device tokens and storing them in a field under your user data. Then, when you query that user, you can find the device tokens to use to send the message.

What goes into sending a FCM from a Firestore to an Android app?

Here is what I have so far:
On Android, user logs in and makes changes to Firestore document.
Firestore document gets updated
cloud function is triggered
cloud function sends message to device(s) using device tokens
On Android, FirebaseMessagingService should receive the message but does not.
I suspect the part I am missing is device token registration. Since my server is Firebase and my users login through Firebase, do I need to take additional steps to send the device token to Firebase so that my cloud function can access it? In other words, do I store them in Firestore myself or do they come standard as part of some "users" collection that's controlled by Firebase? For more context, I adapted my cloud function from an example I found online:
CLOUD FUNCTION:
exports.coolThingIsHappening = functions.firestore.document("coolstuf/{userId}")
.onWrite(async (change, context) => {
console.log("coolThingIsHappening is triggered");
const userId = context.params.userId;
const after = change.after.data();
const payload = {
data: after
}
const tokensSnapshot = await admin.database()
.ref(`/users/${userId}/notificationTokens`).once('value');
if (!tokensSnapshot.hasChildren()) {
const logMsg = `user ${userId} has no notification tokens.`
console.log(logMsg)
return logMsg;
}
console.log("FCM tokens found")
const tokens = Object.keys(tokensSnapshot.val());
const response = await admin.messaging().sendToDevice(tokens, payload);
const tokensToRemove: Promise<void>[] = [];
console.log(`response results: ${response.results.length}`)
response.results.forEach((result, index) => {
console.log(`fcm sent: ${result.messageId}`)
const error = result.error;
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);
});
EDIT
I have proceeded to saving the fcm tokens to Firestore. Any idea how to convert the code above from database-centric to firestore-centric. I am having some trouble. Android code:
val data = mapOf("token" to it)
val collectionName = "users/${uid}/deviceTokens/"
FirebaseFirestore.getInstance().collection(collectionName).document()
.set(data)`
If you want to send messages to devices, you will need to write code to collect the device tokens in your app, and store them or send them to your backend. None of this happens automatically.
I know this is about an year since this question has been asked but it may help someone.
To send notifications to devices, you should make another collection in your firestore where you store all the tokens from users and then you can get token from there to send notification to anyone.

How to send push notifications to multiple device with FCM tokens using cloud functions

First I generated a FCM token and stored in firestore. After that I wrote a cloud functions to send notifications based on FCM token. and I deployed cloud functions it says successfully sent notifications with status ok. But it doesn't displays in mobile device. My Index.js is
'use strict';
const functions = require('firebase-functions');
const Firestore = require('#google-cloud/firestore');
const admin = require('firebase-admin');
const firestore = new Firestore();
const db = admin.firestore();
admin.initializeApp(functions.config().firebase);
exports.hellouser = functions.firestore
.document('users/{token}')
.onWrite(event =>{
var document = event.data.data();
console.log("tokens",document);
var token = ['cdNN0AbYKU0:APA91bEyL0zo3zwHZD8H43Vp7bxAfYgehlVI8LrKktPO2eGuByVDdioysIGxHe5wocwq8ynxRToJPpOve_M59YY_MIRbWLnF9AIgoTwJORXZbw6VBw7']// this is my FCM token.
if(
const payload = {
notification: {
title: "Message",
body: "hi hello",
sound: "default"
}
};
return admin.messaging().sendToDevice(token, payload).then((response)=> {
console.info("Successfully sent notification")
}).catch(function(error) {
console.warn("Error sending notification " , error)
});
});
How to send notifications based on the FCMtoken.
If it's the exact code you use then check syntax near if(. This may help you.Next write some code to go through your response object. Firebase may take your tokens and payload, process them and return 200 OK response but in the response you will have errors. Response has general structure like this: { results:
[ { //stuff related to one token },{ //stuff related to one token } ],
canonicalRegistrationTokenCount: 0,
failureCount: 1,
successCount: 0,
multicastId: SOME_LONG_NUMBER }Take in mind that response.results array has status of each message sent to token in the same order as tokens in your token array. You can see all posible errors in Firebase Documentation. If response.failureCount > 0 then no messages were sent and you should get corresponding error in response.results.Also learn about options variable. options.priority must be 'high' to guarantee fast message delivery. Maybe this will help.

How to send Push Notification Firebase

I am new to Firebase and the main reason I adapted to it from my old MySql DB is the ability to send push notification and dynamic links. I have been trying for the past two days to send notification to a group of people who have subscribed to a topic from my node.js script. The script always returns InternalServerError. I am able to send notification from the Firebase console but that is not good enough for my app as I need to implement dynamic notification (i.e. triggered by one users action).
So far I did not understand what was in the official docs and tried following a tutorial I found and I am currently here
app.get('/push',function(req,res){
/*var title = req.params.title;
var body = req.params.body;*/
// var confName = req.params.name;
var message = { //this may vary according to the message type (single recipient, multicast, topic, et cetera)
to: '/topics/ilisten',
// collapse_key: 'your_collapse_key',
notification: {
title: 'This is Title',
body: 'This is body'
},
data: { //you can send only notification or only data(or include both)
my_key: 'Conf Name here'
}
};
fcm.send(message, function(err, response){
if (err) {
console.log("Something has gone wrong!"+err);
} else {
console.log("Successfully sent with response: ", response);
}
});
})
My first question is what should I do in the to field so that all the users in my app reciece the notification.
I would also like to take a look at correct and complete implementation of this concept with android code. If anyone has such code please share it here as it would help the future Firebase users who cannot understand the official docs like me.
Following is one approach using node-gcm (https://github.com/ToothlessGear/node-gcm)
var gcm = require('node-gcm');
var sender = new gcm.Sender(<sender_key>);
var message = new gcm.Message();
message.addNotification('title', title);
message.addNotification('body', body);
sender.send(message, { topic: "/topics/" + topic }, function (err, response) {
if (err) console.error(err);
else console.log(response);
});

How can i send push notification on any item update event in parse.com

I am using parse for my application
I have one fragment on user which have to write article and save on parse but with not approve
when admin approve that user filed I want to send push notification automatically to that user with particular article is approved message
How can I implement this things..?
Parse.Cloud.afterSave("Data", function(request) {var dirtyKeys = request.object.dirtyKeys();for (var i = 0; i < dirtyKeys.length; ++i) {
var dirtyKey = dirtyKeys[i];
if (dirtyKey === "name") {
//Get value from Data Object
var username = request.object.get("name");
//Set push query
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo("name",username);
//Send Push message
Parse.Push.send({
where: pushQuery,
data: {
alert: "Name Updated",
sound: "default"
}
},{
success: function(){
response.success('true');
},
error: function (error) {
response.error(error);
}
});
return; } } response.success();});
If this is a matter of just hitting "approve", I would create a cloud code function for "Approve article" that is called by the admin tapping an approve button. This function sets the approve status and then calls a function (still in cloud code) for sending the push message to the user.
More on cloud code functions: https://parse.com/docs/cloudcode/guide#cloud-code-cloud-functionshttps://parse.com/docs/cloudcode/guide#cloud-code-cloud-functions
Alternatively the approve button can change status and save the document, and then an afterSave() function in cloud code can handle the push. This is less clear, though, since the afterSave() function will always be called when the record is saved, and it would need to check for status and only send push if the article has been approved.

Categories

Resources