Amrish Kakadiya
Amrish Kakadiya

Reputation: 1023

Android FirebaseMessaging Service onMessageReceived called twice

I have implemented firebase cloud messaging in my Android app. When I send notification from backed or Firebase console onMessageReceived() is triggered twice and generates two notifications on device. I've tried to search on internet but no results found for this problem

here is my code,

MyFirebaseNotificationService.java

public class MyFirebaseNotificationService extends FirebaseMessagingService {
    @Override
    public void onNewToken(String s) {
        super.onNewToken(s);

        MyApp.getInstance().saveFCMToken(s);
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        int notificationId = new Random().nextInt(60000);
        
        String customerId = "";
        Log.e("NOTIF", "" + remoteMessage.getData());

        
        Intent notificationIntent = new Intent(this, SplashActivity.class);
        
        notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        notificationIntent.setAction(Long.toString(System.currentTimeMillis()));
        final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "100")
                .setSmallIcon(R.drawable.ic_app_icon)
                .setColorized(true)
                .setPriority(PRIORITY_HIGH)
                .setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))
                .setContentTitle(Html.fromHtml(remoteMessage.getData().get("title")))
                .setContentText(Html.fromHtml(remoteMessage.getData().get("message")))
                .setAutoCancel(true)
                .setDefaults(Notification.DEFAULT_SOUND)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        createNotificationChannel();
        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
        notificationManager.notify(notificationId, notificationBuilder.build());

    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = "Exchange Customer";
            String description = "Sales Buddy";
            String CHANNEL_ID = "100";
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
            channel.setDescription(description);
            getSystemService(NotificationManager.class).createNotificationChannel(channel);
        }
    }
}

AndroidManifest

  <service android:name=".sevices.MyFirebaseNotificationService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

Permissions in Manifest

 <uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

<uses-feature
    android:name="android.hardware.camera"
    android:required="true" />

On Message received I've logged notification and here is logcat

2019-05-01 15:08:54.415 29417-29501/in.example.one E/NOTIF: {extras={"customerId":"5e341186-6bd4-11e9-9069-44a8422a303b"}, type=exchange, title=Test User:1556703533, message=Test User1}

2019-05-01 15:08:58.542 29417-29501/in.example.one E/NOTIF: {extras={"customerId":"5e341186-6bd4-11e9-9069-44a8422a303b"}, type=exchange, title=Test User:1556703533, message=Test User1}

here you can see same notification log is printing twice and both notifications are displaying on device

Project Gradle File

  dependencies {
    classpath 'com.android.tools.build:gradle:3.4.0'
    classpath 'com.google.gms:google-services:4.2.0'
    classpath 'io.fabric.tools:gradle:1.26.1'

}

Module Gradle File

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.amitshekhar.android:android-networking:1.0.2'
implementation 'com.github.WindSekirun:SectionCalendarView:1.0.5.1'
implementation 'com.github.darsh2:MultipleImageSelect:v0.0.4'
implementation 'com.bogdwellers:pinchtozoom:0.1'

implementation 'com.google.firebase:firebase-core:16.0.8'
implementation 'com.google.firebase:firebase-messaging:17.6.0'
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'
implementation 'com.google.firebase:firebase-database:16.1.0'

}

My Php code

$extras= json_encode(['customerId' => "5e341186-6bd4-11e9-9069-44a8422a303b"]);
$data=array(
    'title'=> "Test User:".time(),
    'message'=> "Test User1",
    'type'=> "exchange",
    'extras'=>$extras   
);
$notification=array(
    'title'=> "Test User:".time(),
    'body'=> "body1",
);
$fields = array
    (
        'to'=>'/topics/test-exchange-persons-sales-buddy',
        'data'  => $data
    );


$headers = array
        (
            'Authorization: key=' . API_ACCESS_KEY,
            'Content-Type: application/json'
        );

    $ch = curl_init();
    curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
    curl_setopt( $ch,CURLOPT_POST, true );
    curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
    curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
    curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
    $result = curl_exec($ch );
    curl_close( $ch );

    echo $result;

Upvotes: 4

Views: 2305

Answers (3)

Grender
Grender

Reputation: 1619

I have the same issue since yesterday (using topics too). As a workaround, until it gets fixed I'm doing this in my FirebaseMessagingService:

private static ArrayList<Long> alreadyNotifiedTimestamps = new ArrayList<>();

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    if (!isDuplicate(remoteMessage.getSentTime())) {
        // send notificaiton here
    }
}

// Workaround for Firebase duplicate pushes
private boolean isDuplicate(long timestamp) {
    if (alreadyNotifiedTimestamps.contains(timestamp)) {
        alreadyNotifiedTimestamps.remove(timestamp);
        return true;
    } else {
        alreadyNotifiedTimestamps.add(timestamp);
    }

    return false;
}

Upvotes: 1

Kulwinder Singh Rahal
Kulwinder Singh Rahal

Reputation: 519

I had also faced similar issue, Because of implementation 'com.google.firebase:firebase-messaging:17.6.0', So then i just used implementation 'com.google.firebase:firebase-messaging:17.3.3' version of messaging then everything worked correctly

Upvotes: 0

Michele Saccomanno
Michele Saccomanno

Reputation: 138

I have tha same problem but with Firebase Messaging Topics. I recive two notification beacuase "onMessageReceived" called twice like you. Maybe a problem from FCM today?

Upvotes: 0

Related Questions