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