I know there are multiple posts like this, but I have tried many solutions and nothing works for me.
I am using a Firebase Cloud Messaging to send notifications. The notification arrives, but it opens the main activity, not the one that I want.
I try and try, but keep failing with starting appropriate activity. Tried different Intent or PendingIntent settings, tried click_action, nothing works for me.
I think that it is not even entering my FirebaseMessagingService, but I did everything like in the Firebase instruction.
manifest:
<service
android:name="com.packagename.FirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<activity android:name="com.packagename.NotificationActivity">
<action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</activity>
FirebaseMessagingService:
public class FirebaseMessagingService extends FirebaseMessagingService {
private static String TAG = "Firebase";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
if(remoteMessage.getNotification()!=null){
Log.d(TAG,"Message body : "+remoteMessage.getNotification().getBody());
sendNotification(remoteMessage.getNotification().getBody(), remoteMessage.getNotification().getTitle());
}
}
private void sendNotification(String body, String title) {
Intent notificationIntent = new Intent(this, NotificationActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.putExtra("notification", body);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notification =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification)
.setContentTitle(getString(R.string.app_name))
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(body)
.setBigContentTitle(title))
.setContentText(body)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setDefaults(NotificationCompat.DEFAULT_SOUND);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0,notification.build());
}
}
Logs after click:
D/StatusBar: Clicked on content of 0|com.mypackagename|0|GCM-Notification:89893881|10177 , PendingIntent{cc15013: android.os.BinderProxy#e3031fc} , Intent { act=com.google.firebase.MESSAGING_EVENT cmp=com.mypackagename/com.google.firebase.iid.FirebaseInstanceIdInternalReceiver (has extras) }
If app in background, notifications directs to the system tray.
After click notification it will redirect to launcher activity which is given in manifest file.
From launcher activity we can call any activity but first it will goto launcher activity.
In Launcher activity we can get notification message contents .
AndroidManifest.xml
<activity
android:name=".view.SplashActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
SplashActivity.Java
public class SplashActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
Bundle bundle = getIntent().getExtras();
if (bundle != null && bundle.get("data")!=null) {
//here can get notification message
String datas = bundle.get("data").toString();
}
}
}
Related
This is my Firbase Service code i just want to open an Another Acivity when app is closed or not running in background i done Everything but it wont work please help
private void createNotification(String messageBody, String title, RemoteMessage message)
{
Intent intent = new Intent(this,NotificationScreen.class);
intent.putExtra("type",message.getData().get("json"));
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent resultIntent = PendingIntent.getActivity( this ,0,intent,PendingIntent.FLAG_ONE_SHOT);
Uri notificationSoundURI = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mNotificationBuilder = new NotificationCompat.Builder( this)
.setContentTitle(title)
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(),R.drawable.icon))
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(notificationSoundURI)
.setContentIntent(resultIntent);
mNotificationBuilder.setSmallIcon(getNotificationIcon(mNotificationBuilder));
//Log.i("data",map.values().toString());
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, mNotificationBuilder.build());
}
private int getNotificationIcon(NotificationCompat.Builder notificationBuilder) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int color = 0x008000;
notificationBuilder.setColor(color);
return R.drawable.icon;
}
return R.drawable.icon;
}
Already applied xml code
<activity android:name=".NotificationScreen"
>
<intent-filter>
<action android:name="NotificationScreen" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Please help unable to understand ..
For Android, you could simply set the value of click_action parameter in your notification payload equal to the intent filter of the corresponding activity that you want to open. As mentioned in the docs (emphasis mine):
The action associated with a user click on the notification.
If specified, an activity with a matching intent filter is launched when a user clicks on the notification.
So for example you have this payload:
{
"to": <TOKEN>,
"notification": {
...
"click_action" : "OPEN_ME"
...
}
}
Then you have an Activity in your manifest that has the corresponding intent-filter name (similar to your post):
<activity android:name=".NotificationScreen">
<intent-filter>
<action android:name="OPEN_ME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
It should open that 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
}
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
I am checking Firebase Cloud Messaging to send notification. Have implemented it already and its receiving notification when app is in open state. But if I close app, its no longer gives notification. Is there any solution for this.
Code:
WebRequest wRequest;
wRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
wRequest.Method = "post";
wRequest.ContentType = " application/json;charset=UTF-8";
wRequest.Headers.Add(string.Format("Authorization: key={0}", AppId));
wRequest.Headers.Add(string.Format("Sender: id={0}", SenderId));
string postData = "{\"registration_ids\":[\"" + regIds + "\"], \"data\": "+ value +"}";
Byte[] bytes = Encoding.UTF8.GetBytes(postData);
wRequest.ContentLength = bytes.Length;
Stream stream = wRequest.GetRequestStream();
stream.Write(bytes, 0, bytes.Length);
stream.Close();
WebResponse wResponse = wRequest.GetResponse();
Messaging service-
public class MessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
sendNotification(data);
}
public void showMessage(Map<String, String> serverData) {
Intent i = new Intent(this,MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,i,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setAutoCancel(true)
.setContentTitle(serverData.get("Title"))
.setContentText(serverData.get("Message"))
.setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(Integer.parseInt(serverData.get("ItemId")),builder.build());
}
private void sendNotification(Map<String, String> serverData) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0 /* request code */, intent,PendingIntent.FLAG_UPDATE_CURRENT);
long[] pattern = {500,500,500,500,500};
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
.setContentTitle(serverData.get("Title"))
.setContentText(serverData.get("Message"))
.setAutoCancel(true)
.setVibrate(pattern)
.setLights(Color.BLUE,1,1)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Integer.parseInt(serverData.get("ItemId")), notificationBuilder.build());
}
}
Main activity-
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseMessaging.getInstance().subscribeToTopic("test");
FirebaseInstanceId.getInstance().getToken();
}
}
Manifest-
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.com.firebasenotify">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".InstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
</application>
</manifest>
There was no issue with the code. I was using Mi note 4, and somehow it does not show notification in Mi4 when app is closed. I tested with other android device and its working fine.
Thanks to Tim Castelijns and Frank van Puffelen for participating in the conversation.
There's good solution and explanation about that issue here. You need to set high priority for notification to tell android react immediately, otherwise it takes couple of minutes to display received notification.
I used Legacy Server Key instead of Server Key it had worked for me.
adding time_to_live key in your POST Payload will solve this problem.The value of this parameter must be a duration from 0 to 2,419,200 seconds, and it corresponds to the maximum period of time for which FCM stores and attempts to deliver the message. "time_to_live" : 3 Refer Firebase Docs
As per FCM docs onMessageReceived() won't be called when app is in the background. You should send a notification object on order to show it up in the system tray and when user clicks it the launcher activity will be open with data as extras with the intent. For payloads you should use data object. see docs and Receive Messages in an Android App
After a Push Notification is received, I want to open an Àctivity when the Notification is pressed.
Here are my Services:
public class GCMIntentService extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle data) {
String title = data.getString("title");
String message = data.getString("message");
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(message)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setTicker(message)
.setAutoCancel(true);
mBuilder.setDefaults(Notification.DEFAULT_LIGHTS);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
Intent myIntent = new Intent(this, MyActivity.class);
PendingIntent intent2 = PendingIntent.getBroadcast(this, 1, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(intent2);
notificationManager.notify(1, mBuilder.build());
}
public class GCMIDListenerService extends InstanceIDListenerService {
#Override
public void onTokenRefresh() {
InstanceID instanceID = InstanceID.getInstance(this);
String token;
try {
token = instanceID.getToken(Resources.getSystem().getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
} catch (IOException e) {
e.printStackTrace();
}
//TODO:send token to the server
}
}
I just did everything following the Google documentation. I implemented that feature for another project sometime ago but it was a bit different, I used my own 'BroadcastReceiver' instead of the 'com.google.android.gms.gcm.GcmReceiver' provides by Google.
Here is my Manifest:
<application>
...
<!-- GCM Push Notifications Config -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="gcm" />
</intent-filter>
</receiver>
<service
android:name=".push.GCMIntentService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name=".push.GCMIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
</application>
Any ideas? Am I missing something?
Here some documentation I have follow:
Google official documentation
CGM tutorial By Dustin Rothwell
And of course I have researched a lot here at stackoverflow.
Thanks!
You have done one minor mistake. You are writing this code for opening activity.
PendingIntent intent2 = PendingIntent.getBroadcast(this, 1, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(intent2);
As you want to open activity you need to create pending intent using getActivity method instead of getBroadcast method.
Hope this will help.