Firebase 'to' send to everyone in Flutter - firebase

Currently I have topics to send push notifications. In particular
all: this is a topic in which I send notifications to everyone
paid: this is a topic in which I send notification only to a small group of users
Today I was upgrading Flutter to the newest firebase package and I encountered this:
<String, dynamic>{
'notification': <String, dynamic>{
'body': 'this is a body',
'title': 'this is a title'
},
'priority': 'high',
'data': <String, dynamic>{
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
'id': '1',
'status': 'done'
},
'to': await firebaseMessaging.getToken(),
},
But wait, isn't 'to' meant to send notifications only to a specific device? Why does
'to': await firebaseMessaging.getToken(),
this send a message to all devices? I am confused because the doc says that 'to' is for specific targets too. Thanks!

The to property in an FCM message determines where it is sent to. The value of the to property can be the device token of a single device, it can be the ID of a device group, or it can be a topic.
It sounds like in your actual code you pass a topic in to, while in the sample in your question it passes a device token.

you can use this Firestore api by google to send push notifications
Future<bool> callOnFcmApiSendPushNotifications(List <String> userToken) async
{
final postUrl = 'https://fcm.googleapis.com/fcm/send';
final data = {
"registration_ids" : userToken,
"collapse_key" : "type_a",
"notification" : {
"title": 'NewTextTitle',
"body" : 'NewTextBody',
}
};
final headers = {
'content-type': 'application/json',
'Authorization': constant.firebaseTokenAPIFCM // 'key=YOUR_SERVER_KEY'
};
final response = await http.post(postUrl,
body: json.encode(data),
encoding: Encoding.getByName('utf-8'),
headers: headers);
if (response.statusCode == 200) {
// on success do sth
print('test ok push CFM');
return true;
} else {
print(' CFM error');
// on failure do sth
return false;
}
}

Related

Flutter push notification's with firebase

In my case, the notification only arrives on the device from which the new item in the list has been added, other users do not receive the notification. I would like other users to receive notifications. Currently I'm using the topic (the same case is with the device token).
Here is my code...
This is my function for post notification on firebase server:
Future postNotification() async {
final postUrl = 'https://fcm.googleapis.com/fcm/send';
final data = {
'to': '/topics/weather',
"collapse_key": "type_a",
"notification": {
"title": channel.name,
"body": channel.description,
},
};
final headers = {
'content-type': 'application/json',
'Authorization':
'key = myserverkey'
};
final response = await http.post(
Uri.parse(postUrl),
body: json.encode(data),
encoding: Encoding.getByName('utf-8'),
headers: headers,
);
print(response.statusCode);
}
For this global functions I get response status code 200 and everything look's fine, for topic name in this example I use weather.I call this function when adding a new element to the list.
This is my function for show notifications and I use this function in home screen of my app:
void showNotification() async {
flutterLocalNotificationsPlugin.show(
0,
channel.name,
channel.description,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channel.description,
importance: Importance.high,
color: Colors.blue,
playSound: true,
icon: '#mipmap/ic_launcher',
),
),
);
}
This is how I call the show Notification function on the home page of my application:
#override
void didChangeDependencies() {
super.didChangeDependencies();
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
RemoteNotification notification = message.notification;
AndroidNotification android = message.notification.android;
if (notification != null && android != null) {
final messageTitle = message.notification.body;
FirebaseMessaging.instance.subscribeToTopic('weather');
showNotification();
print(messageTitle);
}
});
}
Do I need an extra backend to make this work on other devices as well?

How can I prevent to display FCM notification on Flutter app background?

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print('Handling a background message ${message.messageId}');
}
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
I can display background notifications with these snippet codes. But is there any way to not display some specific notification in the background?
For example I don't want to display notifications with data = {title = "call"}
from the sender device u have to send data only notification
await http.post(
Uri.parse('https://fcm.googleapis.com/fcm/send'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'key=$serverKey',
},
body: jsonEncode(
<String, dynamic>{
'data': <String, dynamic>{
'id': '2',
'status': 'done'
},
'to': userToken,
"collapse_key": uid,
},
),
);
add conditions in your _firebaseMessagingBackgroundHandler like
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
if(message.data["title"]=="Call")
{
// show nothing
}
else
{
// show notifications
}
}

easiest way to send firebase push notification from client site in react-native

I am new to react native and I am stuck to send push notification from client side. i have FCM token of every user but need to send a notification to specific user. if you want more clarity please comment and let me know the solution of this
I saw your problem and I have a solution for you. I am already doing it and here's my code.
export const sendPushNotification = async (token, title, body,) => {
//console.log("token==>", token);
const FIREBASE_API_KEY ="<your firebase cloud messaging server key>"
const message = {
registration_ids: [token],
notification: {
title: title,
body: body,
vibrate: 1,
sound: 1,
show_in_foreground: true,
priority: "high",
content_available: true
},
};
let headers = new Headers({
"Content-Type": "application/json",
Authorization: "key=" + FIREBASE_API_KEY
});
let response = await fetch("https://fcm.googleapis.com/fcm/send", {
method: "POST",
headers,
body: JSON.stringify(message)
});
// console.log("=><*", response);
response = await response.json();
// console.log("=><*", response);
};
you can use this function like this
sendPushNotification(
FCMToken,
'title of message',
`this is body of message`,
);
hope it will worked on your side

Flutter FCM how to remove the token when user uninstall the app

I'm developing a Flutter app (using Firebase Firestore and FCM) that aims to send notifications to all devices where the user has signed in. When the user signs out from a device, the token will be removed from Firebase. I am looking for a solution to remove the token when user uninstall the app, and in a way, able to store/update the multiple device tokens for a single user without storing the token based on the android id.
What I am using for sending notification:
final FirebaseMessaging firebaseMessaging = FirebaseMessaging();
Future<Map<String, dynamic>> sendAndRetrieveMessage(context) async {
await firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(sound: true, badge: true, alert: true, provisional: false),
);
await http.post(
'https://fcm.googleapis.com/fcm/send',
headers: <String, String>{
'Content-Type': 'application/json',
'Authorization': 'key=$server_token',
},
body: jsonEncode(
<String, dynamic>{
'notification': <String, dynamic>{
'body': '${widget.content}',
'title': '${widget.title}',
},
'priority': 'high',
'data': <String, dynamic>{
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
'status': 'done',
'body': '${widget.content}',
'title': '${widget.title}',
},
'registration_ids': user_tokens,
},
),
).then((http.Response response){
final int statusCode = response.statusCode;
print("RESPONSE BODY: " + response.body);
print("STATUS CODE: " + statusCode.toString());
if (statusCode < 200 || statusCode > 400 || response.body == null) {
throw new Exception("Error while fetching data");
}
});
final Completer<Map<String, dynamic>> completer =
Completer<Map<String, dynamic>>();
firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
completer.complete(message);
},
onLaunch: (Map<String, dynamic> message) async {
completer.complete(message);
},
onResume: (Map<String, dynamic> message) async {
completer.complete(message);
},
);
return completer.future;
}
I have tried these methods for my notification module:
Update signed-in token in Firebase, but updating only one string also means only sending to the latest signed-in device of the user ignoring the other devices
Subscribe user to user_id topic, but topics are limited to 5 per sending notification. My app needs to send to a list of specific users (undetermined by a common topic, but a set of multiple conditions) and I want to avoid using loops as the notification function needs to work simultaneously for all receiving users
Read HTTP response message to detect failed token, the response returns "NotRegistered" but the response does not return the specific failed token
I would like to know if this is doable in Flutter and if there are solutions/simpler methods for this problem. Thank you

Flutter/Firebase - sending notification to user

Goal: send notification for all user devices.
Problem description: I've problem with sending notification for one user. After registration, I store FCM token in database for user to send notification for him. Problem is that when user will register multiple times - same token will be stored for more than one user.
Example:
user register with emails test#gmail.com and test2#gmail.com
user login to test#gmail.com
other user send notification to test#gmail.com
notification will be send on both accounts (test#gmail.com and test2#gmail.com) instead of only to test#gmail.com
So here's my question - how to send notification to all devices connected to user instead of all users connected with device?
QuerySnapshot ref = await Firestore.instance.collection('users')
.document(_textController.text)
.collection('tokens')
.getDocuments();
ref.documents.forEach((snapshot) async {
http.Response response = await http.post(
'https://fcm.googleapis.com/fcm/send',
headers: <String, String>{
'Content-Type': 'application/json',
'Authorization': 'key=$serverKey',
},
body: jsonEncode(
<String, dynamic>{
'notification': <String, dynamic>{
'body': 'this is a body',
'title': 'this is a title'
},
'priority': 'high',
'data': <String, dynamic>{
'click_action':
'FLUTTER_NOTIFICATION_CLICK',
'id': '1',
'status': 'done'
},
'to': snapshot.data['token'],
},
),
);
});
Thanks for help!
I FOUND SOLUTION!
All you have to do if you have the same problem is deleting token on logout.
final Firestore store = Firestore.instance;
final FirebaseAuth auth = FirebaseAuth.instance
String token = await _fcm.getToken();
await store
<reference to token document>
.delete();
await auth.signOut();

Resources