3

I implemented FCM Push Notifications. The main problem is when app is closed, notifications not arrive when this happen on device.

I tried a lot of thigs for that works; when notification sent the server response with "success", but I never received.

This is full code. Android, Manifiest and server.

Android:

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.accionait.canje365.R;
import com.accionait.canje365.activities.ChatActivity;
import com.accionait.canje365.activities.HomeActivity;
import com.accionait.canje365.constants.Constants;
import com.google.firebase.messaging.RemoteMessage;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
    private static final String TAG = "FCM Service";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        showNotification(remoteMessage);
    }

    private void showNotification(RemoteMessage remoteMessage) {
        Uri uriDefaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext())
        .setSmallIcon(R.mipmap.ic_notification)
        .setLargeIcon((((BitmapDrawable)getResources().getDrawable(R.mipmap.ic_notification)).getBitmap()))
        .setContentTitle("TITLE")
        .setContentText("MESSAGE")
        .setContentInfo("0")
        .setAutoCancel(true)
        .setTicker("Canje365")
        .setSound(uriDefaultSound);

        Intent home = new Intent(this, HomeActivity.class);
        home.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        PendingIntent intent = PendingIntent.getActivity(this, 0, home, PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(intent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(1, builder.build());
    }
}

Server:

var message = {
    to: token,
    data: {valor: 'test'}
};

fcm.send(message, function(err, response){  
    if(err) {
        console.log('Error: ' + err);
    } 
    else {
        console.log('Notificacion enviada: ', response);
    }
});

Manifiest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.accionait.canje365">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<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">

    <service android:name=".sync.RunIntentService" />
    <service android:name=".sync.FirebaseMessagingService">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    <service android:name=".sync.FirebaseIdService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service>

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="MY_API_KEY" />

    <activity
        android:name=".activities.MainActivity"
        android:theme="@style/SplashScreenTheme">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
         android:name=".activities.HomeActivity"
         android:label="@string/title_activity_login"
         android:screenOrientation="portrait">
    </activity>
</application>
</manifest>

What to do with this?

peterh
  • 11,875
  • 18
  • 85
  • 108
  • We are fine thanks for greeting us. I am guessing you are using the Firebase Console to send out notifications right? You have to implement your own server, I know, extra work,went thru the same implemented mine in Java, you can use PHP too. Read this: http://stackoverflow.com/questions/37711082/how-to-handle-notification-when-app-in-background-in-firebase – Manny265 Nov 27 '16 at 20:24
  • and officials docs explaining types of messages and when each is received https://firebase.google.com/docs/cloud-messaging/concept-options – Manny265 Nov 27 '16 at 20:24
  • @Manny264 that is my own server, is not the Firebase Console. I read the docs about types of messages. You can see I send only data-message to handle when app is closed. I've already tried with this. Thanks man! If you have other suggestion, please tell me. Thanks again. –  Nov 28 '16 at 03:39
  • @MatiDB Have you tested sending the same payload via a cURL request or by using postman (see sample from the StackOverflow Documentation [here](http://stackoverflow.com/documentation/google-cloud-messaging/5811/getting-started-with-google-cloud-messaging/20474/send-downstream-messages-from-the-cloud#t=201611280441047741874))? – AL. Nov 28 '16 at 04:41
  • 1
    @AL. Yes, I tested by using Postman. This is the response, but the notification not arrive on device. { "multicast_id": 8973622958220667974, "success": 1, "failure": 0, "canonical_ids": 0, "results": [ { "message_id": "0:1480342544218725%8a20129df9fd7ecd" } ] } What can I do now? :/ –  Nov 28 '16 at 14:19
  • That's odd. Can you post the a sample payload (from the logs) that is sent? – AL. Nov 29 '16 at 01:46
  • Yes, it's odd. What do you mean from the logs @AL. ? I think the bug is in app because the server response with "success". What do you think? Do you have a sample app with this implementation work? Thanks again! –  Dec 01 '16 at 02:19
  • Sorry for the confusion, I just meant the actual payload. – AL. Dec 01 '16 at 08:02
  • 1
    Hi @AL. I found the solution. I have a Huawei and I had and to allow to be run on the background. Below is the answer! Thanks for all! –  Dec 02 '16 at 00:57

2 Answers2

1

In my case I have a Huawei P8 Lite and to allow to be run on the background.

This is the link where You can to find detail abount this case.

Solution on Huawei devices

Community
  • 1
  • 1
1

I faced the same problem. Its a problem in many phone models. I'm just writing this so that out there if anyone faces the same problem can waste a little less time searching for this problem because I wasted a lot! Android M and above devices have battery optimization enabled by default for all apps, which usually stops the background services of our apps. We just have to ask user to disable them, if user choose not to disable them, then I'm sorry..i don't think user is really happy with your app functionality. In order to ask user to enable that--->

Intent intent = new Intent();
        String packageName = getPackageName();
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (pm != null && pm.isIgnoringBatteryOptimizations(packageName))
                intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
            else {
                intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
                intent.setData(Uri.parse("package:" + packageName));
            }
        }
        startActivity(intent);
  • 1
    By any chance you know, how to use the same on Ionic (a hybrid mobile application development platform) – Vasanth May 27 '19 at 11:27