Following requests from some of you on the previous article on Firebase Analytics, today we're going to cover Firebase Cloud Messaging integration in your application developed with Eclipse. It is not much different from the Firebase Analytics integration, so here we go.
dandar3/android-google-firebase-README gives you an overview of the Firebase libraries available to use with your Eclipse project. Have a look at the two YouTube videos at the end covering the installation of the Subversive plugin and the steps to easily import entire project sets like dandar3/android-google-firebase-messaging in your workspace.
On top of that you will have to add your own
You can find a working sample on GitHub in firebase/quickstart-android in the
which then you can use to send messages from Firebase Console to:
Firebase Analytics libraries
dandar3/android-google-firebase-README gives you an overview of the Firebase libraries available to use with your Eclipse project. Have a look at the two YouTube videos at the end covering the installation of the Subversive plugin and the steps to easily import entire project sets like dandar3/android-google-firebase-messaging in your workspace.
You will observe compile errors like Tag ... attribute name has invalid character '$' after importing libraries like android-google-firebase-iid or android-google-firebase-common. To resolve the issue you will have to manually replace ${applicationId} with your application id (Java package) in all AndroidManifest.xml files (use CTRL+H > File Search > Replace...)
Importing google-services.json
Read the Firebase documentation and follow the Processing the JSON File information to manually generate your own values.xml
If you're having trouble with getting this right you could use Android Studio to import firebase/quickstart-android GitHub project, deploy your google-services.json into it and then copy the generated values.xml out.
This is the undocumented part that can only be observed by looking at the AndroidManifest.xml generated by Google Services Gradle plugin (app\intermediates\manifests\full\debug\AndroidManifest.xml)
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="default_web_client_id" translatable="false">{YOUR_CLIENT}/oauth_client/[first client_type 3]</string> <string name="gcm_defaultSenderId" translatable="false">project_info/project_number</string> <string name="firebase_database_url" translatable="false">project_info/firebase_url</string> <string name="google_app_id" translatable="false">{YOUR_CLIENT}/client_info/mobilesdk_app_id</string> <string name="google_api_key" translatable="false">{YOUR_CLIENT}/services/api_key/current_key</string> <string name="google_storage_bucket" translatable="false">project_info/storage_bucket</string> </resources>
AndroidManifest.xml changes
This is the undocumented part that can only be observed by looking at the AndroidManifest.xml generated by Google Services Gradle plugin (app\intermediates\manifests\full\debug\AndroidManifest.xml)
<?xml version="1.0" encoding="utf-8"?> <manifest> [...] <!-- Required permission for App measurement to run. --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <permission android:name="${applicationId}.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" /> <application> [...] <receiver android:name="com.google.android.gms.measurement.AppMeasurementReceiver" android:enabled="true" android:exported="false" > </receiver> <receiver android:name="com.google.android.gms.measurement.AppMeasurementInstallReferrerReceiver" android:enabled="true" android:permission="android.permission.INSTALL_PACKAGES" > <intent-filter> <action android:name="com.android.vending.INSTALL_REFERRER" /> </intent-filter> </receiver> <service android:name="com.google.android.gms.measurement.AppMeasurementService" android:enabled="true" android:exported="false" /> <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <category android:name="${applicationId}" /> </intent-filter> </receiver> <!-- Internal (not exported) receiver used by the app to start its own exported services without risk of being spoofed. --> <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" /> <!-- FirebaseInstanceIdService performs security checks at runtime, no need for explicit permissions despite exported="true" --> <service android:name="com.google.firebase.iid.FirebaseInstanceIdService" android:exported="true" > <intent-filter android:priority="-500" > <action android:name="com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service> <provider android:name="com.google.firebase.provider.FirebaseInitProvider" android:authorities="${applicationId}.firebaseinitprovider" android:exported="false" android:initOrder="100" /> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> </application> </manifest>
On top of that you will have to add your own
FirebaseMessagingService
and FirebaseInstanceIdService
implementations to handle messages and registration tokens as detailed in Firebase documentation > Set Up a Firebase Cloud Messaging App on Android.You can find a working sample on GitHub in firebase/quickstart-android in the
messaging
module. I would recommend reading the module README.md, app/src/main/AndroidManifest.xml and the related classes in /app/src/main/java/com/google/firebase/quickstart/fcm/Testing
If everything was set up correctly and you have implemented a similar logic to the classes mentioned in the above documentation and working sample, you can subscribe through the app to a topic and have messages sent to those subscribed that way (see Send Tipic Messages with Firebase Console) or you can obtain the registration token and send messages to that one device (see Send a Notification to an Android Device).
Here is a test using the sample app. Push Log Token button to get the registration token in logcat:
D/MainActivity( 1983): InstanceID Token: cNtIOWfDiJY:APA91bFat1GNW7yEAj5HdSzsQsPsn-CzN6KtxxzT0h41lo_w5Hg2p8_PJVAgY7hWx_2RrHSmq8Bc7emA_NDXqHEVfzj8hqnbucnJKSeMU48jS2DEdJLcM5eYha3KLIIRvwOie17voHJJ
which then you can use to send messages from Firebase Console to:
D/MyFirebaseMsgService( 1983): From: 348775509088 D/MyFirebaseMsgService( 1983): Message Notification Body: Hello from Firebase Console!See sendNotification() and the note at the end of MyFirebaseMessagingService.java if you want to transform the message into a system notification.
After editing the android manifest file, I created a MyFirebaseMessagingService.java under src/packagename/. When i copied the codes from https://github.com/firebase/quickstart-android/blob/master/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/MyFirebaseMessagingService.java
ReplyDeletei get the following errors
- The import com.google.firebase.messaging cannot be resolved
- FirebaseMessagingService cannot be resolved to a type
- RemoteMessage cannot be resolved to a type
- The constructor Intent(MyFirebaseMessagingService, Class) is undefined
- The method getActivity(Context, int, Intent, int) in the type PendingIntent is not applicable for the arguments - (MyFirebaseMessagingService, int, Intent, int)
- The constructor NotificationCompat.Builder(MyFirebaseMessagingService) is undefined
- The method getSystemService(String) is undefined for the type MyFirebaseMessagingService
How should i solve these problems in MyFirebaseMessagingService.java
It probably means you haven't imported the respective libraries from GitHub into your workspace (I see messaging, iid, support-v4 classes) or you haven't attach firebase-messaging to your Android app project in project Properties > Android > Library section (down).
DeleteThanks! the MyFirebaseMessagingService.java is working now. However after making changes to Mainactivity.java.
DeleteWhen i run the app and click the log token button. I get the following errors
- failed to resolve REGISTER intent, falling back.
- Both Google Play Services and legacy GSF package are missing
- InstanceID Token: null
How should i fix this?
I would make sure to use the latest Google Play Services and Firebase packages (10.0.0 as of now, 10.0.1 should be just a minor fix, soon to be available) and test it on a device that does have Google Play Services installed.
DeleteFrom https://firebase.google.com/docs/cloud-messaging/android/client
"FCM clients require devices running Android 2.3 or higher that also have the Google Play Store app installed, or an emulator running Android 2.3 with Google APIs. Note that you are not limited to deploying your Android apps through Google Play Store."
How to install google play services on the emulator? I am using android 4.1.2
DeleteYou need to start practicing your google.com and stackoverflow.com search skills :-) As it says in the earlier message "or an emulator running Android 2.3 (or higher) with Google APIs".
DeleteThis is an article from Intel going through creating an AVD with Google APIs(as they've helped providing images optimized for working on Windows and Intel CPUs), the screenshots are from a Mac, but the programs are the same really (run "ANDROID_SDK\SDK Manager.exe" and "ANDROID_SDK\AVD Manager.exe").
You will need to install Intel HAXM either from SDK Manager (download from "Extras\Intel X86 Emulator Accelerator" then go and install ANDROID_SDK\extras\intel") or from Intel's website, it's linked in the article.
Now Available: Android SDK x86 System Image with Google APIs
https://software.intel.com/en-us/blogs/2014/03/06/now-available-android-sdk-x86-system-image-with-google-apis
Why is my adblogcat not showing anything?
ReplyDeleteHi! thanks for the information. However when i run the app and click on the log token, the token is generated. I copied the token and pasted into the firebase console registration token. However, after sending the message my android emulator is not receiving any notifications. How should i fix it?
ReplyDeleteHave a look at the firebase/quickstart-android GitHub project mentioned in the post at the end, see the two services at the end of AndroidManifest.xml, you need to implement something along those lines. https://github.com/firebase/quickstart-android/tree/master/messaging/app/src/main
DeleteThey're also mentioned in the official documentation (linked in the article before the Testing section): https://firebase.google.com/docs/cloud-messaging/android/client#manifest
You may be right to ask "why didn't you fully implement it here so we can see?" Because it was meant to tackle just the missing part for Eclipse, libraries and generated parts of the manifest, the rest of it should be just as documented and provided by Google.
PS: Sorry, your comment went into Spam for some reason and could not see it until now.
I created the app as per your instructions but I get this error in my logcat. Any idea whi this might be happening W/System.err(20824): remove failed: ENOENT (No such file or directory) : /data/user/0/com.example.ap/shared_prefs/com.google.android.gms.appid.xml.bak
ReplyDeleteBy the look of it tries to delete a shared preferences backup file that doesn't exist. You didnd't provide a stacktrace so I can't decompile a class to look at it and see what it does, but I would assume maybe you're running this on an emulator without external storage, or missing permission to write on external storage, not sure what's going on. I would suggest opening a new thread on StackOverflow with more details about it. I don't think this is a problem related to the libraries themselves or the directions suggested in this post.
DeleteHey, thanks for this tutorial. I tried it with IntelliJ, not using gradle.
ReplyDeletewithout calling FirebaseApp.initializeApp i get the error:
Default FirebaseApp is not initialized in this process
when calling FirebaseApp.initializeApp the following occurs:
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/gms/R$string;
at com.google.android.gms.common.internal.zzam.(Unknown Source)
at com.google.firebase.FirebaseOptions.fromResource(Unknown Source)
at com.google.firebase.FirebaseApp.initializeApp(Unknown Source)
what's going wrong here?
com.google.android.gms.R$string is in google-play-services-basement.
DeleteIf you go to dandar3/android-google-firebase-README project on GitHub (linked in article above) you can see all the libraries you need grouped by Firebase library.
I would suggest using Eclise to download an entire set easily (see the video explaining how to download an entire project set), then import in IntelliJ all projects from the Eclipse workspace.
thanks for pushing me to the right direction, it's working now, i had to add the corresponding projects in my project.properties as android.library.reference and add the jars to my project libs folder
DeleteGlad to hear you got it working, well done :-)
DeleteHi Dan, Thanks for your information! Really very useful integration. Anywhere github you pushed this code? i need to setup in sencha project, so if i can able to see how you added in sample project then its very useful to me. Thanks b vinoth
ReplyDeleteHi Dan, Few errors i m getting, please can you help this AndroidManifest.xml:86: error: Error: No resource found that matches the given name (at 'value' with value '@integer/google_play_services_version')
ReplyDeleteDear Dan, Please can you helpthis, i m getting error in AndroidManifest.xml:86: error: Error: No resource found that matches the given name (at 'value' with value '@integer/google_play_services_version').
ReplyDeleteThat is part of the google-play-services-basement project (see its res\values\values.xml)
Deletehttps://github.com/dandar3/android-google-play-services-README
Thanks for reply! Thanks lot! I have added those files in lib folder
Deleteandroid-support-annotations.jar
android-support-compat.jar
android-support-core-ui.jar
android-support-core-utils.jar
android-support-fragment.jar
android-support-media-compat.jar
android-support-v4.jar
google-firebase-common.jar
google-firebase-iid.jar
google-firebase-messaging.jar
google-play-services-basement.jar
google-play-services-tasks.jar
But still getting error R.java file also deleted and getting reference i m getting error in AndroidManifest.xml:86: error: Error: No resource found that matches the given name (at 'value' with value '@integer/google_play_services_version').
if you don't mine can you share any sample integration source ?
DeleteYou need to bring those entire projects into your workspace, whatever IDE you are using - you need the JARs as well as the resources from those projects (res folders). You can't just lump the XML resources into your project as they would overwrite, each library project as it's own res\values\values.xml that would simply overwrite each other. The way to do it is to keep them or import them as separate library projects and add them as library references, see this screenshot as an example (your app project > Properties > Android page > Libraries section). https://developers.helpshift.com/static/books/android/eclipse-helpshiftsdk-reference.png
DeleteI'll see if I can make a short video or a post with screenshots to show you how to add the libraries as dependencies to your app for Eclipse, they seem to be harder to find nowadays with Google removing those older references from their documentation.
Deletei add them (your app project > Properties > Android page > Libraries section).
Deletebut show the red cross
not green tick
Hi Dan,
ReplyDeleteCan you please help me
i just want to integrate FCM into eclipse using Cordova
i am facing this error:
java.lang.ClassNotFoundException: Didn't find class "com.google.firebase.messaging.FirebaseMessaging" on path: DexPathList[[zip file "/data/app/io.cordova.hellocordova-2/base.apk"],nativeLibraryDirectories=[/data/app/io.cordova.hellocordova-2/lib/arm64, /vendor/lib64, /system/lib64]]
03-29 18:29:15.053: E/AndroidRuntime(27398): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
Please help me
I'm sorry I haven't used these with Apache Cordoba, but if I were to guess from the error message com.google.firebase.messaging.FirebaseMessaging is missing from your APK - it can be found in google-firebase-messaging.jar meaning, so I would think somehow google-firebase-messaging project is not set as a dependency / library for your project...
DeleteHi Dan, I am using onesignal notification sdk and also used https://github.com/dandar3/android-google-play-services-ads lib Android app was missing the Google Play Services library.
Deleteerror like that
05-02 11:48:33.330: E/OneSignal(10433): java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/gms/gcm/GoogleCloudMessaging;
@Unknown
DeleteCan you give me more of the stack-trace to indicate which class is causing this? What version of Google Play Services / Firebase are you using?
I would suggest removing all Google Play Services and Google Firebase libraries from your workspace and import using Project Sets, see more information in the videos down at the bottom of this page. I'm thinking there is a version incompatibility between two libraries in your workspace, it's easier to remove and add back in, Project Sets should do all the work for you, bringing all required libraries from the same version. Also you get the added bonus that showing the tag / version you can spot them very easily from Project Explorer.
https://github.com/dandar3/android-google-firebase-README
Choose whichever version you want to doesn't have to be latest (15.0.0)
File > Import... > Team > Team Project Set > URL:
https://raw.githubusercontent.com/dandar3/android-google-firebase-messaging/15.0.0/.projectset
Hi
ReplyDeleteTwo simple questions:
1. Is the Support-v4.jar required?
2. The guide of firebase stated the prerequisite is Android 4.0. Will it got crash if running on Android 3.x ?
Sorry I missed your questions.
Delete1. Yes, google-firebase-messaging depends on google-play-services-basement and that depends on android-support-v4. You can see that in the link below and at the bottom there are a couple of videos showing you how to download them all down easily using Team Project Sets.
https://github.com/dandar3/android-google-firebase-README
2. It probably will crash on older APIs, newer versions use minSdkVersion="14", see their AndroidManifest.xml.
Version 10.0.1 is the last one to support API 9 (again, you can check their AndroidManifest.xml)
https://github.com/dandar3/android-google-play-services-README/tree/10.0.1
Also see the release notes:
https://developers.google.com/android/guides/releases#november_2016_-_version_100
"Android version 2.3.x (Gingerbread) Deprecation
Google Play services 10.0.x is the final release that includes full support for Android version 2.3.x (Gingerbread). Apps developed using future SDK releases after 10.0.x will not be able to connect to Google Play services on Android Gingerbread devices. To learn more about your options, including building multiple APKs to extend your app's support for Android Gingerbread, see the Android Developers Blog."
Hey Dan,
ReplyDeletehave you ever done a release build with firebase messaging libs included? I have massive problems with proguard when obfuscating. It throws a lot of Warnings like
Warning: com.google.android.gms.internal.zzw$zza: can't find superclass or interface org.apache.http.client.methods.HttpEntityEnclosingRequestBase
Warning: com.google.android.gms.internal.zzac: can't find referenced class android.net.http.AndroidHttpClient
Warning: com.google.android.gms.internal.zzac: can't find referenced class android.net.http.AndroidHttpClient
Ant build can not be finished with: Please correct the above warnings first.
I created an issue on GitHub and I started to answer it there - it will only get you over the first one reported, but we can take it further there. https://github.com/dandar3/android-google-firebase-README/issues/4
DeleteHi Dan, thank you for your amazing work, I just want to know that are you going to port firebase-database to eclipse soon?
ReplyDeleteThank you, Linh, you're quite welcome. I certainly can look into it, keep an eye on android-google-firebase-README next few days.
DeleteHello Dan and thanks for great work on this! Some legacy projects are still on eclipse! :)
ReplyDeleteI copied also the example services but it seems the following are missing:
import com.firebase.jobdispatcher.Constraint;
import com.firebase.jobdispatcher.FirebaseJobDispatcher;
import com.firebase.jobdispatcher.GooglePlayDriver;
import com.firebase.jobdispatcher.Job;
I included all needed projects and added them as library to my project. I am I missing maybe something?
Thanks!
Athanasios
Thank Athanasios, you're welcome!
DeleteThose classes look like they're part of Google's firebase/firebase-jobdispatcher-android project on GitHub.
https://github.com/firebase/firebase-jobdispatcher-android/tree/master/jobdispatcher/src/main/java/com/firebase/jobdispatcher
How did you get to reference those? You should be able to download the project (Git or ZIP), import "jobdispatcher" folder and add "java" as a source folder.
They were inside the example files. I ended up removing the dependencies. They are only needed if you decide to use the firebase job dispatcher. I guess what you are proposing is gonna work for the people that want to use them. ;) Cheers!
DeleteThanks.
ReplyDeleteI am not actually starting my project. But I finally see the token pop-out in logcat screen.
Thanks for 10000000000000000... time. You save everything.
Hi Dan,
ReplyDeleteCan you please help me
I am facing this error:
Unable to get provider com.google.firebase.provider.FirebaseInitProvider: java.lang.ClassNotFoundException: Didn't find class "com.google.firebase.provider.FirebaseInitProvider"
Didn't find class "com.google.firebase.provider.FirebaseInitProvider"
com.google.firebase.provider.FirebaseInitProvider is part of google-firebase-common project, check if you have that imported in your workspace.
DeleteEach project has a number of dependencies listed on the project page, e.g.:
https://github.com/dandar3/android-google-firebase-messaging
Would recommend to install all necessary project dependencies using the Team Set import feature in Eclipse (notes at the bottom of the page above):
File > Import... > Team > Team Project Set > URL:
https://raw.githubusercontent.com/dandar3/android-google-firebase-messaging/11.4.0/.projectset
See the videos at the bottom of the page below on how to install Eclipse SVN Subversive plugin + connectors and how to easily import entire project sets using the feature (whether Google Firebase or Google Play Store or Android Library Projects, it's the same procedure):
https://github.com/dandar3/android-google-firebase-README/
HTH,
Dan
Hi,
ReplyDeleteThank you for your hardwork.
I have a small problem. I can get the push token fine. When I send a push notification message to a android client I am getting this error when receving the push message
05-10 03:40:11.763: I/RcaHandler(11429): java.lang.RuntimeException: Unable to instantiate receiver com.google.firebase.iid.FirebaseInstanceIdReceiver: java.lang.ClassNotFoundException: Didn't find class "com.google.firebase.iid.FirebaseInstanceIdReceiver" on path: DexPathList[[zip file "/data/app/com.example.firebase_test-1/base.apk"],nativeLibraryDirectories=[/data/app/com.example.firebase_test-1/lib/arm64, /vendor/lib64, /system/lib64]]
05-10 03:40:11.763: I/RcaHandler(11429): at android.app.ActivityThread.handleReceiver(ActivityThread.java:2880)
it seems to be related to multi-dex but I can run the project. I am working on a test app. There is no exta code except the push code in the project
Any idea why ?
Thank you and you are most welcome :-)
DeleteHave you analyzed the APK with dex2jar (https://sourceforge.net/p/dex2jar/wiki/UserGuide/) or apktool (https://ibotpeaches.github.io/Apktool/install/) to see if the class was packaged correctly?
Do you use ProGuard? have you checked the rules to see if the class is removed by the rules or maybe have not imported the library projects fully (I ask cause I see some are taking just the JARs into their project, recommending to import using Project Sets, see the videos at the end of https://github.com/dandar3/android-google-play-services-README)
Do you use Android Support Multidex library (https://github.com/dandar3/android-support-multidex)?
well, i am an idiot. I have mixed up the package names. thats why it cannot find the class name. Now it's working fine. Thanks alot.
DeleteApologies for late reply, I'm glad you sorted it out!
Delete