Amr Yousef
Amr Yousef

Reputation: 594

Firebase Notification Not Showing on Android Device

I am trying to develop a module that will show notifications using Firebase. This module has a 3 function to subscribe and unsubscribe from topics. It also has the two services mentioned in the firebase sample

I know that it is working because it is syncing topics with Firebase console. New topics are being created.

This module is connected to the main app module which uses it.

My problem is that when a notification is sent, I don't receive.

Firebase module code :

Android Manifest

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

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <!-- for plugin -->
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:supportsRtl="true">


        <service
            android:name=".AbleFirebaseMessagingService"
            android:enabled="true"
            android:exported="true">

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


        <service android:name=".FirebaseIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
        </service>
    </application>

</manifest> 

AbleFirebaseMessagingService

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v7.app.NotificationCompat;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import com.ineqe.able.library.MainActivity;

public class AbleFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "AbleFirebaseService";
        @Override
        public void onMessageReceived (RemoteMessage remoteMessage){
            // [START_EXCLUDE]
            // There are two types of messages data messages and notification messages. Data messages are handled
            // here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
            // traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
            // is in the foreground. When the app is in the background an automatically generated notification is displayed.
            // When the user taps on the notification they are returned to the app. Messages containing both notification
            // and data payloads are treated as notification messages. The Firebase console always sends notification
            // messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
            // [END_EXCLUDE]

            // TODO(developer): Handle FCM messages here.
            // Not getting messages here? See why this may be: 
            Log.d(TAG, "From: " + remoteMessage.getFrom());

            // Check if message contains a data payload.
            if (remoteMessage.getData().size() > 0) {
                Log.d(TAG, "Message data payload: " + remoteMessage.getData());
            }

            // Check if message contains a notification payload.
            if (remoteMessage.getNotification() != null) {
                Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
            }

            // Also if you intend on generating your own notifications as a result of a received FCM
            // message, here is where that should be initiated. See sendNotification method below.
        }
        // [END receive_message]

        /**
         * Create and show a simple notification containing the received FCM message.
         *
         * @param messageBody FCM message body received.
         */

    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 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(getApplicationContext())
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("FCM Message")
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
    }

FirebaseIDService

package com.ineqe.firebasenotification;

import android.util.Log;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;

/**
 * Created by brendan on 26/10/2016.
 */

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);

        // TODO: Implement this method to send any registration to your app's servers.
        sendRegistrationToServer(refreshedToken);
    }

    /**
     * Persist token to third-party servers.
     * <p>
     * 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.
    }
}

FireBasePushService

import android.util.Log;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.FirebaseMessaging;
import com.ineqe.able.library.PushService;

/**
 * Created by brendan on 25/10/2016.
 */

public class FireBasePushService implements PushService {
    @Override
    public void initialize() {

        Log.v("Token", FirebaseInstanceId.getInstance().getToken());
        FirebaseMessaging.getInstance().subscribeToTopic("global");
    }

    @Override
    public void addChannel(String channel) {
        FirebaseMessaging.getInstance().subscribeToTopic(channel);
    }

    @Override
    public void removeChannel(String channel) {

        FirebaseMessaging.getInstance().unsubscribeFromTopic(channel);
    }
}

Also I will add the manifest, gradle.build file and the main activity file to show how I reference the firebase module.

Manifest

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

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <permission
     android:name="com.ineqe.hsct.fostering.permission.C2D_MESSAGE"
     android:protectionLevel="signature" />
     <uses-permission android:name="com.ineqe.hsct.fostering.permission.C2D_MESSAGE" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:name=".MyApplication"
        android:theme="@style/AppTheme">



         <meta-data
             android:name="com.google.firebase.messaging.default_notification_icon"
             android:resource="@drawable/ic_not" />

        <activity
            android:name=".WalkthroughActivity"
            android:theme="@style/AppTheme.NoActionBar" />
        <activity
            android:name=".StafDirectoryDetailActivity"
            android:theme="@style/AppTheme2" />
        <activity
            android:name=".MainActivity"
            android:theme="@style/Theme.MyApp"
            android:configChanges="screenSize|orientation"
            android:label="@string/app_name">

        </activity>
        <activity
            android:name=".ExpansionActivity"
            android:configChanges="screenSize|orientation">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>
    </application>

</manifest>

MyApplication.java

import com.ineqe.firebasenotification.FireBasePushService;

public class MyApplication extends com.ineqe.able.library.MyApplication {

    @Override
    public void onCreate() {
        setMainActivity(MainActivity.class);
        setTintAppColor("#00b5cc");
        setSplashImage("hsctf_splash_bg");
        setAppTracker("UA-42956664-12");
        FireBasePushService ps = new FireBasePushService();
        ps.initialize();
        setPushService(ps);
        setLoginImage("hsctf_login_bg");
        setSchool(true);
        setTesting(false);
        setAnswersPage(true);
        setExpansionFiles(false);
        super.onCreate();

    }


}

Gradle.build

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"
    useLibrary 'org.apache.http.legacy'
    defaultConfig {
        applicationId "com.ineqe.hsct.fostering"
        minSdkVersion 16
        targetSdkVersion 23
        multiDexEnabled true
        versionCode 19
        versionName "1.0"
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
    }

}

repositories {
    maven { url 'https://maven.fabric.io/public' }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'me.relex:circleindicator:1.2.1@aar'
    compile 'com.android.support:appcompat-v7:23.2.0'
    compile project(':able')
    compile project(":firebasenotification")


}

What I know right now is :

  1. The app can talk to firebase console and create new topics.
  2. Notification doesn't seem to arrive even when I use the token for the specific device I am working with.

If you have any ideas don't hesitate to comment

Upvotes: 5

Views: 11549

Answers (2)

Amr Yousef
Amr Yousef

Reputation: 594

I figured out where my mistake is. the line :

apply plugin: 'com.google.gms.google-services'

should be added to build.gradle for app module, not the firebase module. In addition, when creating the project the correct way is to enter the package for the app module and save the google-services.json file in the app module not the other firebase module.

To reuse the firebase module (if you have one), always remember to do it as mentioned previously.

Upvotes: 2

Divyesh Patel
Divyesh Patel

Reputation: 2576

First add this filter in firebaseMessanging service:

<action android:name="android.intent.action.RESPOND_VIA_MESSAGE"/>

In firebaseMessanging:

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

        RemoteMessage.Notification notification = remoteMessage.getNotification();

        Map<String, String> data = remoteMessage.getData();
       ShowNotification(notification, data);
    }

    private void ShowNotification(RemoteMessage.Notification notification, Map<String, String> data) {

        Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);

        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 sound = Uri.parse("android.resource://" + getApplicationContext().getPackageName() + "/raw/notification");


        android.support.v4.app.NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setContentTitle(data.get("title"))
                .setContentText(data.get("text"))
                .setAutoCancel(true)
                .setSound(sound)
                .setContentIntent(pendingIntent)
                .setContentInfo("ANY")
                .setLargeIcon(icon)
                .setColor(Color.RED)
                .setSmallIcon(R.mipmap.ic_launcher);


        notificationBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
        notificationBuilder.setLights(Color.YELLOW, 1000, 300);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, notificationBuilder.build());
    }

And In FIrebaseIDservice:

@Override
    public void onTokenRefresh() {
        super.onTokenRefresh();

        String refreshedToken = FirebaseInstanceId.getInstance().getToken();

        FirebaseMessaging.getInstance().subscribeToTopic("GLOBALgroup");

       // sendRegistrationToServer(refreshedToken);   Your METHOD to save TOKENS
    }

Upvotes: 0

Related Questions