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.