I am building a Flutter app. I have a Firestore collection called 'signals' in europe-central2. I have setup Cloud Messaging in my app and it works when the app is in the background. Now I want to make it so that a notification comes out every time a new document is created in my collection of 'signals'. I have tried the following with Cloud Functions:
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
var serviceAccount = require("../../serviceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
//databaseURL: "https://com-rescuer-com-rescuer.europe-central2.firebasedatabase.app"
});
const token = "<the-token-I-got-from-the-emulator-and-works-for-cloud-messaing>";
exports.pushNotifications = functions
.region('europe-central2')
.firestore.document("signals/{docId}").onCreate(
(snapshot) => {
return admin.messaging().sendToDevice(
token,
{
notification: {
title: "A New Notification",
body: "Hello world!",
}
}
);
}
);
However, it doesn't work. With the credential and/or with the databaseURL parameter it throws an error at deploy, and without them, I get a "access denied" message when the function is called (when I see the cloud function logs). I have called firebase init
and installed the firebase tools globally.
on the Flutter side I've done this:
final FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;
final token = await firebaseMessaging.getToken();
print('token $token'); // this is how I get the token for now
firebaseMessaging.requestPermission(
provisional: true,
);
firebaseMessaging.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
I want to:
- be able to show notifications no matter if the app is foreground, background or stopped.
- A bonus would be some kind of targeting. For example, I have a bunch of regions and I would like to send notifications about new signals to users that follow these regions
- The notification would be about a signal from a list of signals. I would like to pass some kind of key to open the specific newly created signal on the front end.
CodePudding user response:
If you are getting notifications when the app is in pause state or closed state that means you will also get the notifications when the app is in open state.
The only thing you have to do is to handle the data that you get from the notification in the open state as it will not show a popup like we get in the closed state.
In order to show a notification to the user in open state use local notification technique.
you need to handle this properly in the flutter app where you initialise the firebase cloud messaging.
CodePudding user response:
This is my code to send notifications using Cloud Functions
// fcm notification
exports.sendNotification = functions.firestore
.document("hubs/{uid}/alerts/{new_alert}")
.onWrite(async(change, context)=>{
const data = change.after.data();
const uid = context.params.uid;
// I keep my client devices' tokens in a separate collection, which I'm fetching here
const clients = await (await admin.firestore().doc(`hubs/${uid}`).get()).data().clients;
const payload = {
"notification":{
"title": "Firebase messaging",
"body": `This might need your attention. ${data.alert}`,
},
};
const options = {};
console.log("sending noti");
return admin.messaging().sendToDevice(clients, payload, options);
});
you can set the path in 3rd line of code to your preferred document using wildcard pattern {}
To open the notification to a new screen in app, please refer to this video
To send notification to people of specific region, given that you're using Cloud Messaging
is that you can create a new campaign for notification targeting specific region. Else your best bet would be to create separate collection for each region.
By default, Firebase Messaging
shows notification when your app is in background or terminated. If your app is running while the notification arrives, it does not pop. Hence only for this scenario, you can use this package for pop up notification.
Happy coding!