With official support
moving away from Eclipse towards Android Studio and Gradle, new things like
Firebase Analytics have become unavailable to developers wanting to continue using Eclipse for their app development. In this post, I will go through the libraries and the configuration required so you can integrate it in your Eclipse project.
Firebase Analytics libraries
dandar3/android-google-firebase-README project (GitHub) gives you an overview of the available Firebase libraires ready 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 an entire project set like Firebase Analytics into 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
There is no Eclipse plugin to do the work that the Google Services Gradle plugin does for Android Studio (I have started working on one, but I can't say when this will be available), so you would have to read the Firebase documentation and follow the
Processing the JSON File information to manually create 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.
You can also try the
web conversion tool I wrote, the conversion is done in your browser through JavaScript like you would do it manually. You need to download your
google-services.json from Firebase Console, then use the tool to open it and will generate
your values.xml just like you would manually do it.
<?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" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<provider
android:name="com.google.firebase.provider.FirebaseInitProvider"
android:authorities="${applicationId}.firebaseinitprovider"
android:exported="false"
android:initOrder="100" />
<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>
</application>
</manifest>
Without these changes you would get all sorts of errors in logcat when running your app, some of them listed below:
11-04 15:56:22.970 E/FA ( 1539): AppMeasurementReceiver not registered/enabled
11-04 15:56:22.971 E/FA ( 1539): AppMeasurementService not registered/enabled
...
11-04 16:01:23.188 W/FA ( 1694): Failed to retrieve Firebase Instance Id
...
11-04 16:01:36.391 E AndroidRuntime: Process: com.google.firebase.quickstart.analytics, PID: 1718
11-04 16:01:36.391 E AndroidRuntime: java.lang.RuntimeException: Unable to start receiver com.google.android.gms.measurement.AppMeasurementReceiver:
java.lang.SecurityException: Neither user 10067 nor current process has android.permission.WAKE_LOCK.
Testing
Enable verbose / debug logging for Firebase Analytics (
docs):
adb logcat -c
adb shell setprop log.tag.FA VERBOSE
adb shell setprop log.tag.FA-SVC VERBOSE
adb logcat -v time -s FA FA-SVC
If everything looks fine you may notice the upload scheduling is nothing close to Google Analytics (1h to 12h) - Steve Ganem, Product Manager at Firebase Analytics, confirms on
StackOverflow he is aware of the need for quicker reporting.
11-05 21:01:21.560 V/FA ( 1418): Upload scheduled in approximately ms: 3599998
One way to trigger the initial upload found by Yapaxi user on the same thread, is to
Clear data for your app. That will not make the information immediately on the Firebase Console web app, it could take up to an hour or more before the reports are made available.
--------- beginning of system
--------- beginning of main
11-05 21:25:17.413 I/FA ( 1761): App measurement is starting up, version: 9877
11-05 21:25:17.413 I/FA ( 1761): To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
11-05 21:25:17.413 D/FA ( 1761): Debug-level message logging enabled
11-05 21:25:17.413 D/FA ( 1761): AppMeasurement singleton hash: 96720111
11-05 21:25:17.418 V/FA ( 1761): Collection enabled
11-05 21:25:17.418 V/FA ( 1761): App package, google app id: com.google.firebase.quickstart.analytics, 1:348775509088:android:a9b2141120408d37
[...]
11-05 21:25:27.931 V/FA ( 1761): Uploading data. app, uncompressed size, data: com.google.firebase.quickstart.analytics, 445,
11-05 21:25:27.931 V/FA ( 1761): batch {
11-05 21:25:27.931 V/FA ( 1761): bundle {
11-05 21:25:27.931 V/FA ( 1761): protocol_version: 1
11-05 21:25:27.931 V/FA ( 1761): platform: android
11-05 21:25:27.931 V/FA ( 1761): gmp_version: 9877
11-05 21:25:27.931 V/FA ( 1761): uploading_gmp_version: 9877
11-05 21:25:27.931 V/FA ( 1761): config_version: 1477992761690000
11-05 21:25:27.931 V/FA ( 1761): gmp_app_id: 1:348775509088:android:a9b2141120408d37
11-05 21:25:27.931 V/FA ( 1761): app_id: com.google.firebase.quickstart.analytics
[...]
11-05 21:25:27.931 V/FA ( 1761): }
11-05 21:25:27.931 V/FA ( 1761): }
11-05 21:25:27.931 V/FA ( 1761): Uploading data. size: 431
11-05 21:25:28.039 V/FA ( 1761): Upload scheduled in approximately ms: 3599999
11-05 21:25:28.042 V/FA ( 1761): Successful upload. Got network response. code, size: 204, 0
That's it - check your data up on
Firebase Console an hour or so later.