I am just adding chat Functionality into my app after adding core function of apps.I start implementing Firebase push notification into app and follow all steps from official documentation.So whenever i send message from Firebase notification console it shows when app in foreground but when app in background it shows these lines in logcat but no notification
09-27 16:11:37.645 19946-19946/com.example.com.appD/dalvikvm: DexOpt: couldn't find field Landroid/os/Message;.sendingUid
09-27 16:11:37.645 19946-19946/com.example.com.appW/dalvikvm: VFY: unable to resolve instance field 135
09-27 16:11:37.645 19946-19946/com.example.com.appD/dalvikvm: VFY: replacing opcode 0x52 at 0x0000
Here is my Firebase Instance ID Service class
public class FireBase_InstanceID_Service extends FirebaseInstanceIdService {
public static final String TAG="==Firebase ID===";
private static final String SubscribeTopic="Chat";
String refreshedToken;
#Override
public void onTokenRefresh() {
super.onTokenRefresh();
refreshedToken= FirebaseInstanceId.getInstance().getToken();
Log.d(TAG,"Here Is Token "+refreshedToken);
FirebaseMessaging.getInstance().subscribeToTopic(SubscribeTopic);
}
private void sendRegistrationToServer(String Token){
//TODO: Send Token To APP server
}
}
Here is my Firebase Messaging Service class
public class FireBase_Messaging_Service extends FirebaseMessagingService {
public static final String TAG="==FireBase MSG==";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.d(TAG,"From "+remoteMessage.getFrom());
if (remoteMessage.getData().size()>0){
Log.d(TAG,"Message Data "+remoteMessage.getData());
}
if (remoteMessage.getNotification()!=null){
Log.d(TAG,"Message Notification Body "+remoteMessage.getNotification().getBody());
}
Log.d(TAG,"FCM Message ID "+remoteMessage.getMessageId());
Log.d(TAG,"FCM Notification Message: "+remoteMessage.getNotification());
Log.d(TAG,"FCM Data Message "+remoteMessage.getData());
showNotification(remoteMessage.getNotification().getBody());
}
private void showNotification(String Message){
Intent intent=new Intent(this, UserProfile.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent=PendingIntent.getActivity(this,5,intent,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder= (NotificationCompat.Builder) new NotificationCompat.Builder (this)
.setAutoCancel(true)
.setContentTitle("New Notification")
.setContentText(Message)
.setSmallIcon(R.drawable.common_google_signin_btn_icon_light_normal)
.setContentIntent(pendingIntent);
NotificationManager manager= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(5,builder.build());
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.com.app">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".Navigation_Drawer"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"></action>
<category android:name="android.intent.category.LAUNCHER"></category>
</intent-filter>
</activity>
<service
android:name=".ImageDownloading"
android:enabled="true"
android:exported="false">
</service>
<!--FIREBASE SERVICES -->
<service android:name=".FireBase_Messaging_Service">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"></action>
</intent-filter>
</service>
<service android:name=".FireBase_InstanceID_Service">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"></action>
</intent-filter>
</service>
<!--FIREBASE SERVICES -->
</application>
</manifest>
So for me i am unable to get push notification in Notification Tray in background or when app is closed With these entries in logcat (which i don't understand)
This is working as intended, notification messages are delivered to your onMessageReceived callback only when your app is in the foreground. If your app is in the background or closed then a notification message is shown in the notification center, and any data from that message is passed to the intent that is launched as a result of the user tapping on the notification.
You can specify a click_action to indicate the intent that should be launched when the notification is tapped by the user. The main activity is used if no click_action is specified.
When the intent is launched you can use the
getIntent().getExtras();
to retrieve a Set that would include any data sent along with the notification message.
For more on notification message see docs.
Related
I have a small application where I receive the message from the Firabase cloud Messaging just fine while the app is running our while is on background. I search a lot about this and I could not find a proper answer on how to receive/create notifications in android while the app is closed so please do not think this is a duplicate question. Can someone show me an example about this and how its done?
This is my Firebase messaging service class
public class MyFirebaseMessagingService extends FirebaseMessagingService {
public static final String tag = "TAG";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(tag,"FROM"+remoteMessage.getFrom());
//check if message contains data
if(remoteMessage.getData().size()>0){
Log.d(tag,"Message Data" + remoteMessage.getData());
}
//check if message constains notification
if(remoteMessage.getNotification() != null){
sendNotification(remoteMessage.getNotification().getBody());
}
}
private void sendNotification(String body){
Intent i = new Intent(this,MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,i,PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Firebase CLoud Messaging")
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0,notificationBuilder.build());
}
}
This is my manifest
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
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=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
As per the docs, there are two types of notifications you can send through FCM.
Notification message
Data message
The firebase console can only send the first type of message. And the Notification message will be handled by the system if your app is in the backgroud, but it won't work if your app is stopped.
Switch to your own API, and send data messages.
So after hours with this problem and with the help of #Mauker I finally did it. These are the steps I took and all the information I received from the internet.
First of all forget Firebase Cloud Message to send notifications to your mobile app.
Second use postman to do those actions.
Notifications are of two types, group notifications where all the people receive the notification at the same time and direct notifications where the notification itself is only for the user to see.
1º If you want group notifications you have to do in you Application launcher class this:
FirebaseMessaging.getInstance().subscribeToTopic("groupNameChoosenByYou");
2º Then you have to create a class to handle this
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
String myCustomKey = data.get("title"); //received from postman POST as you can see above
Intent i = new Intent(this,MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,i,PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(myCustomKey)
.setContentText(myCustomKey+myCustomKey)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0,notificationBuilder.build());
}
}
3º Go to postman and do this in your body
This should be your URL : https://fcm.googleapis.com/fcm/send
{
"to":"/topics/groupNameChoosenByYou",
"data":
{
"title":"Your title",
"message":"Your message"
}
}
4º While in postman and do this in your Headers
Authorization -> Project settings in Firebase -> Cloud Messaging and take the Server key
Content-type -> application/json
5º If you want to do a direct notification for some specific user in the
"to":"/topics/groupNameChoosenByYou", replace with the device token id that is generated on the first connection with firebase(when the application is installed)
6º If you want to send notifications while the application is closed some ROMs dont allow this except facebook, whatsapp(golden apps) etc you must go to your battery optimization and put your app in the protected application(this changes from brand to brand). The ideal approach is to give the user an initial popup to help him do this.
This is what I learned and it works for me. Any question post above, I will try to research more about this and update while I get more information.
I’m new to android.I programmed an app that uses Firebase to get push notifications. If I send a notification from the Firebase interface, the device receives the notification only when the app is running. Is there a way to get the notifications when the app is not running or at least to get all the unseen notifications when the app starts up?
Thank you in advance!
I add my code...
This is the class extending the FirebaseMessagingService:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
public MyFirebaseMessagingService() {
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
sendNotification(remoteMessage.getNotification().getBody());
}
private void sendNotification(String messageBody)
{
//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);
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher_round);
notificationBuilder.setContentTitle("My app");
notificationBuilder.setContentText(messageBody);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSound(defaultSoundUri);
//notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0,notificationBuilder.build());
}
}
and this is the class extending the FirebaseInstanceIdService:
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService{
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(refreshedToken);
}
private void sendRegistrationToServer(String token)
{
}
}
Finally, this is the manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="user.pushnotificationexample">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
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=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service
android:name=".MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application>
</manifest>
This is Xamarin Android solution, but it should get you close to native.
Try test sending a "data" push notification from an online tester like "pushwatch". Make sure to click the json checkbox and add a json payload that includes the key, "data":
{"data": {"title":"This is a title!","body":"This is the body text!"}}
The OnMessageReceived(RemoteMessage message) method, message parameter, has a dictionary property "Data": i.e. message.Data. You'll find the json payload key value pairs (title & body) in that dictionary.
Note, if the app is STOPPED, the user will OPEN the notification and Android will open the app, targeting the Activity used in the pending intent created and used to build the local notification (see below). You will need to handle the notification intent from the OnCreate method of your target Activity ( otherwise if the app is running, you'll handle the intent from an override of OnNewIntent).
public class MainActivity....
{
protected override void OnCreate(Bundle bundle)
{
...
var pushExtra = Intent.GetStringExtra("your.pushextra.key");
if(pushExtra != null)
{
MyType myType = JsonConvert.Deserialize<MyType>(pushExtra);
//if you have a framework like MVVM or startup process
//and your type
//is used for app navigation, you may need to store
//the string value in shared preferences and deserialize
//and use it later
//after the app has completely finished starting
}
}
}
Save yourself some effort, if you need a type or dictionary here, make sure to serialize the object when putting the extra (when you create the local notification) and then deserialize the pushExtra to your concrete type to use an instance of it above. You may find most examples put a string, or int or dictionary of key value pairs.
void ConfigureLocalNotification(MyType typeInstance)
{
...
var intent = new Intent(context, typeof(MainActivity));
var jsonData = JsonConvert.SerializeObject(typeInstance);
Log.Info(TAG, $"Adding IntentExtra: {jsonData}");
intent.PutExtra("your.pushextra.key", jsonData);
intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop |
ActivityFlags.IncludeStoppedPackages); //| ActivityFlags.NewTask);
var pendingIntent = PendingIntent.GetActivity(context, 0, intent,
PendingIntentFlags.OneShot);
....
NotificationCompat.Builder builder = null;
builder = new NotificationCompat.Builder(context ...);
builder.SetContentIntent(pendingIntent) ....
}
Hope this helps
I can receive push notification when my app is in foreground or background
I added FcmBroadcastReceiver extends WakefulBroadcastReceiver in order to get push
when I close my application.
But I continue without receiving notifications when the app is closed.
Thanks for your help.
manifest.xml
<pre>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="<package>.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.package.name.permission.C2D_MESSAGE" />
<receiver
android:name="<package>.Notification.FcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="<package>" />
</intent-filter>
</receiver>
<service android:name=".Notification.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
public class FcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("receiver","okey");
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
MyFirebaseMessagingService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
public class MyFirebaseMessagingService extends FirebaseMessagingService {
Intent i;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
System.out.println("******************** + getMessageType "+remoteMessage.getMessageType());
System.out.println("******************** + getFrom "+remoteMessage.getFrom());
System.out.println("******************** + getMessageId "+remoteMessage.getMessageId());
System.out.println("******************** + getTo "+remoteMessage.getTo());
System.out.println("******************** + getData "+remoteMessage.getData());
System.out.println("******************** + getData().get(message) "+remoteMessage.getData().get("message"));
System.out.println("******************** + getData().get(title) "+remoteMessage.getData().get("title"));
showNotification(remoteMessage.getData().get("type"),remoteMessage.getNotification().getTitle(),remoteMessage.getNotification().getBody());
}
private void showNotification(String to , String title, String message) {
i = new Intent(this,ProfileActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,i, PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setAutoCancel(true)
.setContentTitle(title)
.setContentText(message)
.setSound(defaultSoundUri)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(0,builder.build());
}
}
<code>
The issue that I can see in your code is that you are implementing the FireBase push notification but you are trying to implement that in a way that was used to implement GCM. You don't need to set any Broadcast Receivers, Firebase is doing that by itself. You just have to run "FirebaseMessagingService". The services looks like this:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated.
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
}
}
As you can see it has it's own "onMessageReceived" method that takes care of Broadcast Receiver's functionality.
Check this tutorial, it will help you to understand:
https://www.codementor.io/flame3/send-push-notifications-to-android-with-firebase-du10860kb
Note: If you want your app to work in each situation even app is in background, foreground or even closed then you need to send some data through payload in your notification.then it will work for all conditions. To do that you need your own server, Firebase doesn't facilitate for that.
I've searched a lot about notifications when the app is in the background or closed. I'm using Firebase Cloud Messaging by the way. It won't work for me. I've used the Android setup and when the app is in the foreground or the phone is not locked the notification is received.
When installed the token is printed correctly and subscribed to the topic.
When I send a notification when the app is active in the foreground (so screen is unlocked and app is shown) I receive the notification and title as stated in the onMessageReceived.
When I send a notification when the app is not shown but is still in recent apps and screen is unlocked I receive the notification with title and message as stated in notification payload.
When I send a notification when the app is not shown but is still in recent apps and screen is locked nothing is received.
When I send a notification when app is *closed and removed from recent apps nothing is received.
How can I change this so the app will always receive the notifications, even when closed or the phone is locked?
Ps. I read about the Doze modus with protected apps, even when I put my app with the protected ones I receive nothing. I'm testing on a Huawei P8 Lite.
AndroidManifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme" >
<activity android:name=".activities.MainActivity"
android:configChanges="orientation"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".services.MyAppFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".services.FirebaseIDService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<receiver android:name=".services.NotificationReceiver" />
</application>
Gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.google.firebase:firebase-core:9.2.0'
compile 'com.google.firebase:firebase-messaging:9.2.0'
}
apply plugin: 'com.google.gms.google-services'
FirebaseMessagingService
public class MyAppFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated.
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
showNotification(getApplicationContext());
}
public static void showNotification(Context context){
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("FCM Message")
.setContentText("FCM Body")
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setPriority(Notification.PRIORITY_MAX)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
FirebaseInstanceIDService
public class FirebaseIDService extends FirebaseInstanceIdService {
private static final String TAG = "FirebaseIDService";
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
System.out.println("Devicetoken: " + refreshedToken);
FirebaseMessaging.getInstance().subscribeToTopic("/topics/myapp");
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(refreshedToken);
}
/**
* Persist token to third-party servers.
*
* Modify this method to associate the user's FCM InstanceID token with any server-side account
* maintained by your application.
*
* #param token The new token.
*/
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
}
}
Notification payload
{
"to": "/topics/mytopic",
"priority": "high",
"notification": {
"sound": "default",
"badge": "1",
"body": "the body text",
"title": "title text"
},
"data": {
"id": "id",
"channel": "channel"
}
}
EDIT - Add code for WakeFulBroadcastReceiver
public class NotificationReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// cancel any further alarms
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmMgr.cancel(alarmIntent);
completeWakefulIntent(intent);
// start the GcmTaskService
MyAppFirebaseMessagingService.showNotification(context);
}
}
UPDATE PAYLOAD
If I change my payload to the suggested way in the comments like this it is still not working. Maybe it has something to do with the Huawei P8 Lite that I'm testing on with Android 6.0.1 installed.
{
"to": "/topics/mytopic",
"priority": "high",
"data": {
"sound": "default",
"badge": "1",
"body": "the body text",
"title": "title text"
}
}
UPDATE 2.0
I've tested on multiple devices and versions. On devices with Android 5 it was working fine, also without app open and screen locked. Only device it wasn't working was my own Huawei P8 Lite. Still can't figure out why it's not working on that one.
When the app is closed, it shutdowns the service. You must to restart the service.
On your Application class, implements ActivityLifecycleCallbacks and on onActivityDestroyed restart the service with an alarm.
public class YourApplication extends Application implements Application.ActivityLifecycleCallbacks {
#Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
}
#Override
public void onActivityDestroyed(Activity activity) {
Intent restartService = new Intent(getApplicationContext(), MyAppFirebaseMessagingService.class);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(),1,restartService,PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME,5000,pendingIntent);
}
}
I also had issues with devices not receiving the notifications when they were closed, like they would be after a restart.
Turned out, it wasn't working with a DEBUG version of the solution, so that had to be tested in RELEASE MODE. For those using Android Studio, press the Green Play Button next to the debug button.
Firebase has different types of notifications, and each has special handling.
Assuming you're using a data push, you don't need special handling or a WakefulBroadcastReceiver.
If you're using a notification push, the notification will appear automatically in the system tray. You cannot do any special handling there.
Check the official documents here: https://firebase.google.com/docs/cloud-messaging/android/receive
I developing an Ionic 2 app and testing on Android emulator.
When the app is in background and the notification has no title, no message and content-available=1 the notification should be sent directly to app notification handler. But its not happening.
I can receive notifications with the app in foreground.
If I have a title and a message I receive the notification in the notification area. But I need to send the notification directly to the app in silent mode, without pass by the notification area.
Here is my code to send push notifications:
{
"delay_while_idle": true,
"priority": "high",
"sound": "default",
"color": "FFFF00",
//payload
"data": {
"content-available": "1",
"some_var": "some_value",
"ohter_var": "other_value",
}
}
How could I sent silent notifications to my Android app?
Android GCM and FCM both also work when app background.
For that you need to add below service classes at manifest with intent Filter.
<!-- [START gcm_listener] -->
<service
android:name=".gcm.GcmListener"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name=".gcm.TokenRefreshService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<service
android:name=".gcm.RegistrationIntentService"
android:exported="false" />
<!-- [END gcm_listener] -->
public class GcmListener extends GcmListenerService {
}
public class TokenRefreshService extends InstanceIDListenerService {
#Override
public void onTokenRefresh() {
super.onTokenRefresh();
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
To get token:
public class RegistrationIntentService extends IntentService {
// TODO: Rename actions, choose action names that describe tasks that this
private String TAG = "RegistrationIntentService";
public RegistrationIntentService() {
super("RegistrationIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken("PRODUCT_ID",
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
}
}