Rakesh
Rakesh

Reputation: 1236

Android App crash with Firebase (Null Pointer Exception)

I'm trying to integrate FCM in my Android app developed in Android Studio by referencing https://firebase.google.com/docs/android/setup. On App startup, it's getting crashed due to an NPE.

EDIT :
1. Device Used to test: Samsung Note 3
2. OS : 5.0
3. Support Repository and Google Services are updated in Android SDK
4. Commenting the line apply plugin: 'com.google.gms.google-services' from app's build.gradle doesn't cause this issue.The issue has something to do with it.

Here's the logcat :

 creating new AssetManager and set to /data/app/com.att.digitallife.pes-1/base.apk
 D/FirebaseApp: com.google.firebase.auth.FirebaseAuth is not linked. Skipping initialization.
 W/InstanceID/Rpc: Found 10017
 D/FirebaseApp: com.google.firebase.crash.FirebaseCrash is not linked. Skipping initialization.
 I/FA: App measurement is starting up, version: 9683
 I/FA: To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
 I/FA: To enable faster debug mode event logging run:
                                                               adb shell setprop firebase.analytics.debug-mode 

   15651-15651/com.nytshift.ergo.pas D/PAS  I/FirebaseInitProvider: FirebaseApp initialization successful
   15651-15651/com.nytshift.ergo.pas D/PAS  : Service created
15651-15651/com.nytshift.ergo.pas D/PAS     ### Service ::: onStart()
15651-15651/com.nytshift.ergo.pas D/PAS    : ###Service::Something unknown happened...null
15651-15651/com.nytshift.ergo.pas D/PAS     D/AndroidRuntime: Shutting down VM
15651-15651/com.nytshift.ergo.pas D/PAS    E/AndroidRuntime: FATAL EXCEPTION: main
                                                                         Process: com.nytshift.ergo.pas, PID: 15651
                                                                         java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.google.android.gms.common.ConnectionResult.isSuccess()' on a null object reference
                                                                             at com.google.android.gms.common.internal.zze$zzi.zzh(Unknown Source)
                                                                             at com.google.android.gms.common.internal.zze$zzk.zzaua(Unknown Source)
                                                                             at com.google.android.gms.common.internal.zze$zza.zzc(Unknown Source)
                                                                             at com.google.android.gms.common.internal.zze$zza.zzv(Unknown Source)
                                                                             at com.google.android.gms.common.internal.zze$zze.zzauc(Unknown Source)
                                                                             at com.google.android.gms.common.internal.zze$zzd.handleMessage(Unknown Source)
                                                                             at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                             at android.os.Looper.loop(Looper.java:145)
                                                                             at android.app.ActivityThread.main(ActivityThread.java:5942)
                                                                             at java.lang.reflect.Method.invoke(Native Method)
                                                                             at java.lang.reflect.Method.invoke(Method.java:372)
                                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)

Here's the Project's build.gradle :

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.0.0'
        classpath 'com.google.gms:google-services:3.0.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Here's how my App's build.gradle looks like:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 20
    buildToolsVersion "23.0.3"
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }

        // Move the tests to tests/java, tests/res, etc...
        instrumentTest.setRoot('tests')
        // Move the build types to build-types/<type>
        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
        // This moves them out of them default location under src/<type>/... which would
        // conflict with src/ being used by the main source set.
        // Adding new build types or product flavors should be accompanied
        // by a similar customization.
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
    lintOptions {
        abortOnError false
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
    productFlavors {
        x86 {
            ndk {
                abiFilter "x86"
            }
        }
        arm {
            ndk {
                abiFilters "armeabi-v7a", "armeabi"
            }
            minSdkVersion 17
        }
    }
    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/notice.txt'
    }
    defaultConfig {
        applicationId "com.nytshift.ergo.pas"
        minSdkVersion 17
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.google.firebase:firebase-core:9.6.1'
    compile 'com.google.firebase:firebase-messaging:9.6.1'
}
apply plugin: 'com.google.gms.google-services'

FireBaseInstanceIDService.java :

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {

    private static final String TAG = "MyFirebaseIIDService";

    /**
     * Called if InstanceID token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the InstanceID token
     * is initially generated so this is where you would retrieve the token.
     */
    // [START refresh_token]
    @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
        PESLog.debug("Inside onTokenRefresh****");
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);

        // 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);
    }
    // [END refresh_token]


    /**
     * 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) {
        // TODO: Implement this method to send token to your app server.
    }
}

MyFirebaseMessagingService.java :

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";



    public void onMessageReceived(RemoteMessage remoteMessage) {

        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());
            //Calling method to generate notification
            //sendNotification(remoteMessage.getNotification().getBody());
        }
        Toast.makeText(getApplicationContext(), "Push notification: " + remoteMessage.getNotification().getBody(), Toast.LENGTH_LONG).show();

        // 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.
     * This method is only generating push notification.
     * @param messageBody FCM message body received.
     */
    private void sendNotification(String messageBody) {
        Intent intent = new Intent(this, PESEmergencyHomeScreen.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 = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.androidwidget_logo)
                .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());
    }
}

Manifest :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.nytshift.ergo.pas"
    android:versionCode="7"
    android:versionName="0.9.3">

    <uses-sdk android:minSdkVersion="17" />



    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.INTERNET" />

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.GET_TASKS" />


    <uses-feature
        android:name="android.hardware.telephony"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.location"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.location.network"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.location.gps"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.wifi"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.touchscreen"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.camera.front"
        android:required="false" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true"></uses-feature>


    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <!-- *** End ZDA library *** -->
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <!-- Keeps the processor from sleeping when a message is received. -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:hardwareAccelerated="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <receiver
            android:name="urls for GCM receiver"
            android:permission="com.google.android.c2dm.permission.SEND"
            android:process=":Service">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="com.nytshift.ergo.pas" />
            </intent-filter>
        </receiver>

        <activity
            android:name=".login.SplashScreen"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
                <category android:name="android.intent.category.BROWSABLE"></category>


            </intent-filter>
        </activity>

        <service
            android:name=".alert.Service"
            android:label="Service"></service>

        <receiver android:name=".zos.NotificationsHandler">
            <intent-filter>
                <action android:name="urls" />
            </intent-filter>
        </receiver>


<!-- FireBase starts -->
    <service android:name=".firebaseservice.MyFirebaseMessagingService"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    <service android:name=".firebaseservice.MyFirebaseInstanceIDService"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>
    </application>

</manifest>

What could be the issue? Please help.

Upvotes: 0

Views: 4011

Answers (2)

Rakesh
Rakesh

Reputation: 1236

After days of investigation, I've finally found what causes the Null Pointer Exception. There was a google-play-services.jar residing in libs folder of the project.(added for some other module and not for FireBase) That conflicts with
apply plugin: 'com.google.gms.google-services' which we add for FireBase.

I had to remove the jar from libs folder of my project and added the same as a dependency like this :

compile 'com.google.android.gms:play-services:10.0.1'

Upvotes: 0

teck wei
teck wei

Reputation: 1385

I don't really get it how u setup for your FCM so I suggest you create a new project test it so you got an idea how to implement it to your main app. FCM setup is much more simple than GCM.

You don't have to watch multiple tutorial just follow the doc.By the way forget anything you learn about GCM.

In your manifest remove any relevant code regarding GCM and replace it with this code then you will be good to go.

     <service
        android:name=".MyFirebaseMessagingService"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    <!-- [END firebase_service] -->
    <!-- [START firebase_iid_service] -->
    <service android:name=".MyFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

If you wondering why you don't need receiver in your manifest to receive FCM it is just because why GCM deprecated LOL.

Don't forget to insert google-services.json file

Upvotes: 1

Related Questions