Firebase push notifications device id is valid only once - android

I have firebase push notifications set up in my android app. The first time I launch an app, I print out the device id in my FirebaseInstanceIdService. When I try to send a notification to this device id from the firebase console, it says that it was sent successfully, but I don't receive it in my FirebaseMessagingService. If I try to send once more, I get the following error:
This is how I initialize services inside manifest.xml:
<service
android:name=".MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseInstanceIDService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
FirebaseInstanceIdService:
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d("TEST", "Refreshed token: " + refreshedToken);
super.onTokenRefresh();
sendRegistrationToServer(refreshedToken);
}
private void sendRegistrationToServer(String token) {
// TODO: Implement this method to send token to your app server.
}
}
FirebaseMessagingService:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d("TEST", "From: " + remoteMessage.getFrom());
sendNotification("sfa");
}
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, NewsFeedActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_app_icon)
.setContentTitle("FCM Message")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 , notificationBuilder.build());
}
}
This is how I initialize FirebaseApp inside my main activity onCreate method:
FirebaseApp.initializeApp(this);

Token will be refreshed on certain conditions:
App deletes Instance ID
App is restored on a new device
User uninstalls/reinstall the app
User clears app data
You have to make sure that you are using the same token that stored in your app to send the notifications to the app. If you accidentally reinstall or clear your app data, you might want to retrieve the new token before sending the notification.

Related

Why will my android notification not send?

I am sending DATA payload from Postman, so the notification should be processed in onMessageReceived regardless of whether the app is in foreground or background.
According my logs and testing, onMessageReceived is fired, but the notifications are not showing (doesn't depend if the app is in foreground or background).
in manifest I have:
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service> <!-- [END firebase_iid_service] -->
<service
android:name=".MyFirebaseInstanceIDService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
and here is MyFirebaseMessagingService.java:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(#NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String title = "";
if (Objects.requireNonNull(remoteMessage.getData()).get("title") != null)
title = remoteMessage.getData().get("title");
String message = "";
if (Objects.requireNonNull(remoteMessage.getData()).get("message") != null)
message = remoteMessage.getData().get("message");
Log.e("notification",title);
sendNotification(title, message);
}
private void sendNotification(String title, String body) {
Intent i = new Intent(this, Novinky.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pi = PendingIntent.getActivity(this,
0, // Request code
i,
PendingIntent.FLAG_ONE_SHOT);
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this,
getString(R.string.default_notification_channel_id))
.setSmallIcon(R.mipmap.ic_notify)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setSound(sound)
.setContentIntent(pi);
NotificationManager manager =
(NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.notify(0, builder.build());
}
}
So I have Log.e("notification",title); there, and it is executed properly, but the notify is not received.
Before I send also a notification+data via Postman, that worked, but that is only an automatic notification not handled by app, so now I want to send only DATA payload and handle it in the app, but for some reason it doesn't work.
You need to make sure you have created your notification channel in your app. A good way to do this is as follows:
public class App extends Application {
#Override
public void onCreate() {
super.onCreate();
createNotificationChannel();
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel nChan = new NotificationChannel(
getString(R.string.default_notification_channel_id),
"My_Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(nChan);
}
}
}
Creating your notification channel in the onCreate() of your app is a good idea as you don't have to worry about it for the rest of the application life time.

Android: Notification not delivered to user using Firebase Cloud Message

I use Firebase Cloud Message at the first time . I connected my app to Firebase and used this tutorial but there isn't any notification
Here is my code .
in the AndroidManifest.xml
<service
android:name=".MyFirebaseInstanceIDService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
In MyFirebaseInstanceIDService
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
private static final String FRIENDLY_ENGAGE_TOPIC = "football";
#Override
public void onTokenRefresh() {
String token = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "FCM Token: " + token);
// Once a token is generated, we subscribe to topic.
FirebaseMessaging.getInstance()
.subscribeToTopic(FRIENDLY_ENGAGE_TOPIC);
}
}
In MyFirebaseMessagingService
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFMService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Handle data payload of FCM messages.
Log.d(TAG, "FCM Message Id: " + remoteMessage.getMessageId());
Log.d(TAG, "FCM Notification Message: " +
remoteMessage.getNotification());
Log.d(TAG, "FCM Data Message: " + remoteMessage.getData());
}
}
And here is the messages that I sent in Firebase Console .
you need to create a notification then it will show on notification tray.
now when your on message received method called it will only prints log.
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request
code */, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri =
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new
NotificationCompat.Builder(this)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setPriority(Notification.PRIORITY_MAX)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationID() /* ID of notification */,
notificationBuilder.build());

Why PendingIntent opens the launcher activity of the app rather than specific activity?

I am using firebase to send notification. It will open ResultActivity when user click on notification. It is working fine when app is in foreground. But when app is in background, it open the HomeActivity (which is the launcher activity of the app) rather than ResultActivity. I can't understand whats the problem?
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder.setContentTitle(getResources().getString(R.string.app_name));
notificationBuilder.setContentText(remoteMessage.getNotification().getBody());
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
Intent intent = new Intent(getApplicationContext(), ResultActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
This is an nice way to test click_action mapping. It requires an intent filter like the one specified in the FCM docs:
<intent-filter>
<action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Also, remember, this will only work if the app is in the background. If it is in the foreground you will need to implement an extension of FirebaseMessagingService. In the onMessageReceived method,you will need to manually navigate to your click_action target
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//This will give you the topic string from curl request (/topics/news)
Log.d(TAG, "From: " + remoteMessage.getFrom());
//This will give you the Text property in the curl request(Sample Message):
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
//This is where you get your click_action
Log.d(TAG, "Notification Click Action: " + remoteMessage.getNotification().getClickAction());
//put code here to navigate based on click_action
}

FCM - Message Not Displayed in Header

I'm trying to implement FCM on my apps. The tutorial source was from here.
The Push Notification was delivered successfully, but why isn't the message displayed in the header? (just like when receiving WhatsApp message). It just shows silently in the back list (after we scroll down the header). Also the push notification doesn't produce any sounds.
Here're my code :
AndroidManifest.xml :
<service android:name="com.myapps.TokenService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service android:name="com.myapps.FCMMessageReceiverService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
FCMMessageReceiverService.java :
public class FCMMessageReceiverService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d("Notification Received",remoteMessage.getNotification().getBody());
sendNotification(remoteMessage.getNotification().getBody());
sendSnackbar(remoteMessage.getNotification().getBody());
}
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(messageBody)
.setAutoCancel(false)
.setSound(defaultSoundUri);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notificationBuilder.build());
}
private void sendSnackbar(String messagebody)
{
}
}
TokenService.java :
public class TokenService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
//super.onTokenRefresh();
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.w("notification", refreshedToken);
sendRegistrationToServer(refreshedToken);
}
private void sendRegistrationToServer(String token) {
}
}
<service
android:name=".MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
Just add two attributes android:enabled and android:exported as shown above in AndroidManifest.xml

Firebase Push Notification [duplicate]

This question already has answers here:
Push notification works incorrectly when app is on background or not running
(3 answers)
Closed 6 years ago.
I implemented Firebase for push notification in my Android app. I implemented two services for register the token and for create the notification when it is detected. When my app is launch it's working but when my app is closed it doesn't working.
public class FirebaseinstanceIdService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.e("Firebase", refreshedToken);
MainActivity.setFirebaseToken(refreshedToken);
}
}
public class MyFirebaseMessageService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//Displaying data in log
//It is optional
Log.e(TAG, "From: " + remoteMessage.getFrom());
Log.e(TAG, "Notification Message Body: " + remoteMessage.getData().get("title"));
//Calling method to generate notification
sendNotification(remoteMessage.getData());
}
//This method is only generating push notification
//It is same as we did in earlier posts
private void sendNotification(Map<String, String> notification) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(notification.get("title"))
.setContentText(notification.get("body"))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
And my manifest :
<service
android:name=".FirebaseinstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseMessageService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
And my request :
{
"to": "ex1CtVz5bbE:APA91bHiM_BCun62A9iCobF1yV26Dwn-hYCDhkYPoWEG5ZdqH0P28UsE5q1v7QibwAX7AJ290-9en9L6f548_2b7WEbJ8RPEWlIotLczjjCP7xEOWqeJk6Iz44vilWYvdu4chPwfsvXD",
"data": {
"title": "Notification",
"body": "Message",
}
}
I already found a few solutions in StackOverflow but it doesn't work in my case. I have an API Rest which call the API Request Post : https://fcm.googleapis.com/fcm/send
So, there is my question : Does Firebase handle push notification when the app is closed and how to ?
Thank you for your answers
FCM does support notifications when app is closed. Your code seems to be OK, so I suppose battery economizers (or power savers) can kill your notifications. I had such problems on my Asus Zenfone, also they were reported in cases of using Huawei and Xiaomi. Just disable them or add your app in exception list, if there is one. Also there is a new power-saving mode in recent releases of Android, try to disable it too.

Categories

Resources