Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase analytics event logging in multi-process app

I have integrated Firebase analytics into my app which has two process : a Background process and a UI process. What I experienced using Firebase was that I'm able to log events from the UI process but not from the Background process.

I can see through Firebase logs on the Android Studio console that though the events are logged but are never scheduled to be uploaded on the Firebase console when being logged from the Background process. Is this a behaviour that Firebase analytics follows - logging events only from a single process? If so, then how does it decide from which process to log events?

I need to log events from both the processes in order to understand the complete user experience, his app health and some other important parameters.

All help is appreciated.

like image 893
Siddharth2092 Avatar asked Jul 14 '16 09:07

Siddharth2092


1 Answers

To log Firebase Analytics events from more than one process you need to initialize Firebase manually in the second process. The semi-automated Firebase setup largely expects single-process apps, and requires additional setup work otherwise for most of its APIs (except Crash Reporting).

Essentially you call the following upon initialization of the second process, assuming that you configured Firebase via the google-services.json file and Google Services Gradle plugin:

FirebaseApp.initializeApp(context, FirebaseOptions.fromResource(context))

The slightly trickier part can be how to ensure that this is only called once, and only in the second process. One approach is to mimic what Firebase itself does for the first process (via Manifest merging) - define a ContentProvider. So in your Manifest add something like the following:

<provider
    android:name=".MyFBProvider"
    android:authorities="org.mydomain.mytestapp.MyFBProvider"
    android:process=":myexternalprocess"
    android:exported="false"
    android:syncable="false" />

Your ContentProvider looks essentially like this, plus empty overrides of all abstract methods:

public class MyFBProvider extends ContentProvider {

    private static boolean created = false;

    @Override
    public boolean onCreate() {
        if (created) {
            // Workaround for https://issuetracker.google.com/issues/37045392
            return false;
        }

        Context context = getContext();
        FirebaseApp.initializeApp(context, FirebaseOptions.fromResource(context));
        created = true;

        // Return false to mimic behavior of FirebaseInitProvider.
        // It should keep the pseudo ContentProvider from being a real one.
        return false;
    }

    ...
}

Using a ContentProvider ensures that the code is run before everything else during process initialization, and only in the process that you specify.

like image 153
Uli Avatar answered Oct 03 '22 08:10

Uli