react-native-firebase icon indicating copy to clipboard operation
react-native-firebase copied to clipboard

[πŸ›] πŸ”₯ Analytics not working on release APK

Open elozino-eryk opened this issue 5 months ago β€’ 24 comments

Issue

Describe your issue here


Analytics events are not being logged on release builds. However, there are being logged on debug events in real time.

Project Files

Javascript

Click To Expand

package.json:

    "@react-native-firebase/analytics": "^23.3.1",
    "@react-native-firebase/app": "^23.3.1",
    "@react-native-firebase/messaging": "^23.3.1",
    "react-native": "0.77.0",
    "react": "18.3.1",
import {
  FirebaseAnalyticsTypes,
  getAnalytics,
  getAppInstanceId as firebaseGetAppInstanceId,
  logEvent as firebaseLogEvent,
  setAnalyticsCollectionEnabled as firebaseSetAnalyticsCollectionEnabled,
} from '@react-native-firebase/analytics';

export class FirebaseAnalyticsService {
  private static analytics: FirebaseAnalyticsTypes.Module = getAnalytics();

  public static async setCollectionEnabled(enabled: boolean): Promise<void> {
    try {
      await firebaseSetAnalyticsCollectionEnabled(this.analytics, enabled);

      if (__DEV__) {
        console.log(
          `[FirebaseAnalyticsService] Analytics collection ${
            enabled ? 'enabled' : 'disabled'
          }`,
        );
      }
    } catch (error) {
      if (__DEV__) {
        console.error(
          '[FirebaseAnalyticsService] Failed to set analytics collection:',
          error,
        );
      }
    }
  }

  public static async getAppInstanceId(): Promise<string | null> {
    try {
      return await firebaseGetAppInstanceId(this.analytics);
    } catch (error) {
      if (__DEV__) {
        console.error(
          '[FirebaseAnalyticsService] Failed to get App Instance ID:',
          error,
        );
      }
      return null;
    }
  }

  public static async logEvent(
    event:
      | ReservedFirebaseAnalyticsEvent
      | CustomFirebaseAnalyticsEvent
      | string,
    params?: Record<string, unknown>,
  ): Promise<void> {
    try {
      await firebaseLogEvent(this.analytics, event.toString(), params);

      if (__DEV__) {
        console.log(
          `[FirebaseAnalyticsService] Event logged: ${event}`,
          params,
        );
      }
    } catch (error) {
      if (__DEV__) {
        console.error(
          `[FirebaseAnalyticsService] Failed to log event: ${event}`,
          error,
        );
      }
    }
  }

  /**
   * Convenience wrapper for select_content
   */
  public static async logSelectContent(
    contentType: string,
    itemId: string,
  ): Promise<void> {
    return this.logEvent(ReservedFirebaseAnalyticsEvent.SelectContent, {
      content_type: contentType,
      item_id: itemId,
    });
  }
}


// In my root navigator
  useEffect(() => {
    (async () => {
      const appInstanceId = await FirebaseAnalyticsService.getAppInstanceId();
      await FirebaseAnalyticsService.logEvent(
        CustomFirebaseAnalyticsEvent.AppInstanceId,
        {appInstanceId},
      );
    })();
  }, []);

firebase.json for react-native-firebase v6:

{
  "react-native": {
    "analytics_auto_collection_enabled": true,
    "messaging_auto_init_enabled": true,
    "messaging_ios_auto_register_for_remote_messages": true,
    "messaging_android_notification_channel_id": "high-priority",
    "messaging_android_headless_task_timeout": 30000,
    "google_analytics_automatic_screen_reporting_enabled": true,
    "messaging_ios_foreground_presentation_options": []
  }
}

iOS

Click To Expand

ios/Podfile:

  • [ ] I'm not using Pods
  • [x] I'm using Pods and my Podfile looks like:
  config = use_native_modules!
  $RNFirebaseAnalyticsWithoutAdIdSupport = true

  use_react_native!(
    :path => config[:reactNativePath],
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )
  
  pod 'FirebaseCore', :modular_headers => true
  pod 'FirebaseCoreInternal', :modular_headers => true
  pod 'FirebaseInstallations', :modular_headers => true
  pod 'GoogleUtilities', :modular_headers => true

AppDelegate.m:

// N/A

Android

Click To Expand

Have you converted to AndroidX?

  • [x] my application is an AndroidX application?
  • [x] I am using android/gradle.settings jetifier=true for Android compatibility?
  • [ ] I am using the NPM package jetifier for react-native compatibility?

android/build.gradle:


buildscript {
    ext {
        buildToolsVersion = "35.0.0"
        minSdkVersion = 24
        compileSdkVersion = 35
        targetSdkVersion = 35
        ndkVersion = "27.1.12297006"
        kotlinVersion = "2.0.21"
    }
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle")
        classpath("com.facebook.react:react-native-gradle-plugin")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
        classpath("com.google.gms:google-services:4.4.2")
    }
}

apply plugin: "com.facebook.react.rootproject"

android/app/build.gradle:

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


dependencies {
    // The version of react-native is set by the React Native Gradle Plugin
    implementation("com.facebook.react:react-android")
    implementation project(':react-native-splash-screen')
    implementation 'androidx.core:core:1.13.1'
    implementation 'androidx.appcompat:appcompat:1.5.0'  // or the latest version
    implementation("androidx.activity:activity:1.9.+")  // or the latest version


    if (hermesEnabled.toBoolean()) {
        implementation("com.facebook.react:hermes-android")
    } else {
        implementation jscFlavor
    }
}

android/settings.gradle:

// N/A

MainApplication.java:

// N/A

AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools">

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

  <uses-feature android:name="android.hardware.telephony" android:required="false" />

  <application
    android:name=".MainApplication"
    android:label="@string/app_name"
    android:icon="@mipmap/ic_launcher"
    android:roundIcon="@mipmap/ic_launcher"
    android:allowBackup="false"
    android:theme="@style/AppTheme"
    android:supportsRtl="true">
    <activity
      android:name=".MainActivity"
      android:label="@string/app_name"
      android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
      android:launchMode="singleTask"
      android:screenOrientation="portrait"
      android:windowSoftInputMode="adjustResize"
      android: exported="true">
    </activity>
  </application>
</manifest>

Environment

Click To Expand

react-native info output:

 OUTPUT GOES HERE

System:
  OS: macOS 15.6.1
  CPU: (11) arm64 Apple M3 Pro
  Memory: 138.27 MB / 18.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 22.16.0
    path: /var/folders/px/ws4dqjkn063gwsm5_mvxhl5w0000gn/T/yarn--1758879086801-0.47891096171310377/node
  Yarn:
    version: 1.22.22
    path: /var/folders/px/ws4dqjkn063gwsm5_mvxhl5w0000gn/T/yarn--1758879086801-0.47891096171310377/yarn
  npm:
    version: 10.9.2
    path: /usr/local/bin/npm
  Watchman:
    version: 2025.05.26.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.16.2
    path: /Users/eryk/.rbenv/shims/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 25.0
      - iOS 26.0
      - macOS 26.0
      - tvOS 26.0
      - visionOS 26.0
      - watchOS 26.0
  Android SDK:
    API Levels:
      - "34"
      - "35"
      - "36"
    Build Tools:
      - 34.0.0
      - 35.0.0
    System Images:
      - android-28 | Google ARM64-V8a Play ARM 64 v8a
      - android-33 | Google Play ARM 64 v8a
      - android-34 | ARM 64 v8a
      - android-34 | Google Play ARM 64 v8a
      - android-35 | Google APIs ARM 64 v8a
      - android-35 | Google Play ARM 64 v8a
      - android-36 | Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2025.1 AI-251.26094.121.2513.14007798
  Xcode:
    version: 26.0.1/17A400
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.13
    path: /usr/bin/javac
  Ruby:
    version: 3.2.0
    path: /Users/eryk/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.1
    wanted: 15.0.1
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.77.0
    wanted: 0.77.0
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true
  • Platform that you're experiencing the issue on:
    • [ ] iOS
    • [x] Android
    • [ ] iOS but have not tested behavior on Android
    • [x] Android but have not tested behavior on iOS
    • [ ] Both
  • react-native-firebase version you're using that has this issue:
    • e.g. 5.4.3
  • Firebase module(s) you're using that has the issue:
    • e.g. Instance ID
  • Are you using TypeScript?
    • Y/N & VERSION "typescript": "5.0.4"

elozino-eryk avatar Sep 26 '25 09:09 elozino-eryk

Hey there, when you mean not working, is it not logging events at all? In debug mode you need to manually configure it through cli it which I am assuming you did here: https://rnfirebase.io/analytics/usage#android so it is strange to me it doesnt work in release. Can you show me how you are initializing analytics and give me some reproduction steps?

MichaelVerdon avatar Sep 29 '25 05:09 MichaelVerdon

Hi @MichaelVerdon, thank you for reaching out. You’re correct, it’s not logging events in the release build. However, in debug mode, it logs all events as expected.

To reproduce the issue: I have a class called FirebaseAnalyticsService where the initialization takes place, and I use it throughout my code. I’m currently utilizing the modular API.

This is what my FirebaseAnalyticsService class looks like

import {
  FirebaseAnalyticsTypes,
  getAnalytics,
  getAppInstanceId as firebaseGetAppInstanceId,
  logEvent as firebaseLogEvent,
  setAnalyticsCollectionEnabled as firebaseSetAnalyticsCollectionEnabled,
} from '@react-native-firebase/analytics';

export class FirebaseAnalyticsService {
  private static analytics: FirebaseAnalyticsTypes.Module = getAnalytics();

  public static async setCollectionEnabled(enabled: boolean): Promise<void> {
    try {
      await firebaseSetAnalyticsCollectionEnabled(this.analytics, enabled);

      if (__DEV__) {
        console.log(
          `[FirebaseAnalyticsService] Analytics collection ${
            enabled ? 'enabled' : 'disabled'
          }`,
        );
      }
    } catch (error) {
      if (__DEV__) {
        console.error(
          '[FirebaseAnalyticsService] Failed to set analytics collection:',
          error,
        );
      }
    }
  }

  public static async getAppInstanceId(): Promise<string | null> {
    try {
      return await firebaseGetAppInstanceId(this.analytics);
    } catch (error) {
      if (__DEV__) {
        console.error(
          '[FirebaseAnalyticsService] Failed to get App Instance ID:',
          error,
        );
      }
      return null;
    }
  }

  public static async logEvent(
    event:
      | ReservedFirebaseAnalyticsEvent
      | CustomFirebaseAnalyticsEvent
      | string,
    params?: Record<string, unknown>,
  ): Promise<void> {
    try {
      await firebaseLogEvent(this.analytics, event.toString(), params);

      if (__DEV__) {
        console.log(
          `[FirebaseAnalyticsService] Event logged: ${event}`,
          params,
        );
      }
    } catch (error) {
      if (__DEV__) {
        console.error(
          `[FirebaseAnalyticsService] Failed to log event: ${event}`,
          error,
        );
      }
    }
  }

  /**
   * Convenience wrapper for select_content
   */
  public static async logSelectContent(
    contentType: string,
    itemId: string,
  ): Promise<void> {
    return this.logEvent(ReservedFirebaseAnalyticsEvent.SelectContent, {
      content_type: contentType,
      item_id: itemId,
    });
  }
}

This is what my firebase.json file looks like

{
  "react-native": {
    "analytics_auto_collection_enabled": true,
    "messaging_auto_init_enabled": true,
    "messaging_ios_auto_register_for_remote_messages": true,
    "messaging_android_notification_channel_id": "high-priority",
    "messaging_android_headless_task_timeout": 30000,
    "google_analytics_automatic_screen_reporting_enabled": true,
    "messaging_ios_foreground_presentation_options": []
  }
}

If you’d like, I can create a sample repo, but this is the only code I have in my codebase for analytics.

elozino-eryk avatar Sep 29 '25 09:09 elozino-eryk

Brilliant, also can you please clarify are you using an Expo or standard React Native project?

MichaelVerdon avatar Sep 29 '25 09:09 MichaelVerdon

Brilliant, also can you please clarify are you using an Expo or standard React Native project?

I am using a standard React Native project (Bare CLI)

elozino-eryk avatar Sep 29 '25 09:09 elozino-eryk

Given your setup, I think it would be helpful if you could provide me a reproduction repo I could use my own internal app config on (google-services.json e.t.c). Would you be willing to do so please?

MichaelVerdon avatar Sep 29 '25 10:09 MichaelVerdon

@MichaelVerdon here is reproduction repo https://github.com/elozino-eryk/firebase-analytics.

Thank you.

elozino-eryk avatar Sep 29 '25 12:09 elozino-eryk

follow

ShadyElsharnobyChefaa avatar Sep 29 '25 13:09 ShadyElsharnobyChefaa

I encountered the same issue: events are sent successfully but do not appear in the Debug View or Live View.

ShadyElsharnobyChefaa avatar Sep 29 '25 13:09 ShadyElsharnobyChefaa

after one day i check the event and find it on board but still the debug view not working in ios and android and the realtime also

ShadyElsharnoby avatar Sep 30 '25 07:09 ShadyElsharnoby

after one day i check the event and find it on board but still the debug view not working in ios and android and the realtime also

There is a flag you have to enable to get the debug to work in realtime

ios: https://rnfirebase.io/analytics/usage#ios android: https://rnfirebase.io/analytics/usage#android

elozino-eryk avatar Sep 30 '25 07:09 elozino-eryk

@elozino-eryk i know and did it already and see firebase logs in Xcode the debug mode is enabled and event successfully uploaded to console

ShadyElsharnoby avatar Sep 30 '25 07:09 ShadyElsharnoby

hey there @elozino-eryk I was unfortunately not able to get the app running but it was still helpful, I suspect this issue might be to do with your implementation. Event names like appInstanceID that you have should be in lower case and underlines like app_instance_id. Have you also tested this on a physical device? Can you try follow the steps here https://firebase.google.com/docs/analytics/get-started?platform=web and see if you can get it working that way on release?

MichaelVerdon avatar Sep 30 '25 08:09 MichaelVerdon

hey there @elozino-eryk I was unfortunately not able to get the app running but it was still helpful, I suspect this issue might be to do with your implementation. Event names like appInstanceID that you have should be in lower case and underlines like app_instance_id. Have you also tested this on a physical device? Can you try follow the steps here https://firebase.google.com/docs/analytics/get-started?platform=web and see if you can get it working that way on release?

I switched to this approach below, and it was the same result I got. While testing on debug mode, I was able to get the logs in near real-time but after generating a release build, the logs are not being sent.

import { getAnalytics, logEvent } from '@react-native-firebase/analytics';

const analytics = getAnalytics();

export const customLogEvent = async () => {
  console.log('test analytics logged');
  return await logEvent(analytics, 'test', {
    test: 'test',
  });
};

elozino-eryk avatar Sep 30 '25 10:09 elozino-eryk

Considering it is working on debug and not release also makes me suspect it could be an obfuscation issue where analytics related classes may be stripped for optimisation purposes. Can you try adding this to your proguard-rules.pro file?:

# Keep Firebase Analytics
-keep class com.google.firebase.analytics.** { *; }
-keep interface com.google.firebase.analytics.** { *; }

MichaelVerdon avatar Oct 01 '25 07:10 MichaelVerdon

Hello πŸ‘‹, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

github-actions[bot] avatar Oct 29 '25 07:10 github-actions[bot]

hello i have an issue similar but not analytics , onSnapshot callback (listener) of real time stop (not update data) in android release mode RN 0.81.3 firebasePckages V 23.5.0 & 21... both nor working

ahmedshalaby24 avatar Nov 12 '25 16:11 ahmedshalaby24

There are many things that change between release mode and debug mode, a lot of which is that it runs on actual devices etc and aggressive manufacturer power savings comes in to play (triple-check this: https://dontkillmyapp.com/)

if it were an artifact of minimization, you'll want to alter your release build - temporarily for testing - to not minifiy the android code.

That is, this variable should be set to know, however you do that in however you build your system -

https://github.com/react-native-community/rn-diff-purge/blob/da93a57b7fe52c1d48e694dec0e6d9f33e5de1cd/RnDiffApp/android/app/build.gradle#L60

https://github.com/react-native-community/rn-diff-purge/blob/da93a57b7fe52c1d48e694dec0e6d9f33e5de1cd/RnDiffApp/android/app/build.gradle#L104

If it is already false or minimization is disabled, then it has nothing to do with proguard and likely nothing to do with how the app is built, but more to do with it's execution context (real devices with power-saving happening...)

adb logcat would also be interesting to watch, on the real device, as you reproduce the issue

mikehardy avatar Nov 12 '25 20:11 mikehardy

  • Thx Mikehardy for ur reply , but i think their is an issue with RN latest versions as everything was working fine until upgrading my RN from 73 to 81 ,
  • Both those 2 lines u referred to in build.gradle already exists,
  • what if their is an issue regarding power saving and battery life over proper functionality , will the next update of package includes this issue handling ?

ahmedshalaby24 avatar Nov 13 '25 08:11 ahmedshalaby24

  • those two lines exist, okay - but what are their settings? That is, are you minifying or not? The goal is to turn off proguard / minimization in order to make sure that isn't the cause. You don't indicate what setting you have
  • there is nothing this package can do about manufacturer power saving, those are device-specific, and involve settings and user education

mikehardy avatar Nov 13 '25 11:11 mikehardy

its value is false , and also i didnt use power saving mode

ahmedshalaby24 avatar Nov 13 '25 11:11 ahmedshalaby24

then it makes no sense, to me, why it would behave differently in debug vs release, except that the execution environment is different. That is, that perhaps you are only doing debug things on an emulator, and only doing release things on a real device. Is that typically the case when you reproduce this? Alternatively, the javascript itself is bundled differently between release and debug, and perhaps the differences there are contributing to the problem.

mikehardy avatar Nov 13 '25 11:11 mikehardy

Regarding this except that the execution environment is different. That is, that perhaps you are only doing debug things on an emulator, and only doing release things on a real device. Is that typically the case when you reproduce this? No this is not what happened everything is the same even in debug mode i am using my real device firestore listener is working well and listen for any change , but once i generate a build for testing and ran it in the same real device the listener stops after a while and stop reading changes comes from firestore ( on android only), ios is working fine

the only solution make this works after RN update version is to disable the newArchitecture

ahmedshalaby24 avatar Nov 13 '25 11:11 ahmedshalaby24

@ahmedshalaby24 okay, so if I understand correctly:

  • on a real device (what device exactly)
  • with a release build but not a debug build
  • even with native minification (proguard) turned off
  • on react native 81 but not on react native 73
  • on new architecture but not old architecture
  • you have a firestore listener that works well and receives changes that stops receiving changes "after a while" (how long?)

So there are still some questions before we have a reproduction - what's your actual device (make and model) and how long before the listeners stop working?

Also, we are on react-native 0.82.1 now as the latest stable release of react-native, it is always possible that something is fixed and we should focus obsessively on making sure our software is up to date while testing, so we don't chase the ghosts of bugs that are already fixed in newer versions...

mikehardy avatar Nov 13 '25 12:11 mikehardy

Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/MyPath/node_modules/@react-native-firebase/app/lib/common' is not supported resolving ES modules imported from /MyPath/node_modules/@react-native-firebase/analytics/lib/index.js Did you mean to import "@react-native-firebase/app/lib/common/index.js"?

"@react-native-firebase/analytics": "^23.7.0", "@react-native-firebase/app": "^23.7.0" "expo": "~53.0.22", "react": "19.0.0", "react-dom": "19.0.0",

the above error occurs when doing expo prebuild, how to fix it

enhbolorZB avatar Dec 09 '25 03:12 enhbolorZB