dpa99c / cordova-plugin-firebasex

Cordova plugin for Google Firebase
MIT License
570 stars 458 forks source link

[FEATURE] Transition to Firebase Crashlytics #335

Closed dpa99c closed 3 years ago

dpa99c commented 4 years ago

Currently this plugin uses the original Crashlytics SDK which is part of the Fabric SDK. Since Google acquired Fabric, they have merged Crashlytics into Firebase so Fabric is now deprecated and will shut down on 31 March 2020, though it's my understanding that Fabric-based Crashlytics will continue to function after this date so long as the Fabric project has been transitioned to Firebase.

Therefore we should move the plugin from (the deprecated) Fabric Crashlytics to Firebase Crashlytics as outlined in the Firebase docs.

However, the Firebase Crashlytics API (currently in Beta) is not an exact mapping of the Fabric API - some API functions have changed signature or are even are not supported.

For example, currently this plugin uses the recordCustomExceptionName API method to send a custom stacktrace to Crashlytics for non-fatal errors. This allows replacing the auto-generated native stacktrace (no use in a Cordova app) with a Javascript stacktrace generated by stacktrace.js (the same approach is used by react-native-firebase).

However, the new Firebase Crashlytics API does not currently support custom stack traces so we'd be unable to bring this feature across.

zmoshansky commented 4 years ago

I've recently received a deprecation notice that the fabric SDK will no longer function after November 15, 2020.

To support some semblance of custom stack trace, the new Crashlytics SDK does have support for customKeys which may help augment this missing behaviour.

dpa99c commented 4 years ago

Looks like react-native-firebase has an open PR with a solution to the custom stack traces so based on that it should be possible to perform the migrations to Firebase Crashlytics SDK without losing that functionality.

dpa99c commented 3 years ago

PR #432 has been submitted to resolve this - I will regression test ASAP

dpa99c commented 3 years ago

This has been implemented on the dev branch.

I've successfully tested on iOS but currently not seeing any crash data for Android using the new Firebase Crashlytics implementation. If someone else could also give the dev branch and test and confirm if they see crashlytics data for Android, that'd be great.

To install the plugin direct from the dev branch:

cordova plugin add https://github.com/dpa99c/cordova-plugin-firebasex#dev
Roshankd1 commented 3 years ago

@zmoshansky any luck with testing crash report for Android?

dpa99c commented 3 years ago

I'm testing this and still unable to get crash details to show in the Firebase Console Crashlytics Dashboard for Android. It seems that Firebase is being notified of the crash as it's causing the "crash free users" statistic to change but the crash details are not appearing in the dashboard.

image

I'll also need to fix the NDK crash reporting for Android (for Cordova apps containing C/C++ libraries invoked via the NDK) since crashes originating in a compiled C library are not being recorded at all on Android (not even in "crash free users").

dpa99c commented 3 years ago

I finally got Android crash reporting working:

image

Thanks to this comment on SO, I ran in platforms/android/:

./gradlew cleanBuildCache && ./gradlew --refresh-dependencies

Then forced a crash, then I saw in the logcat:

2020-06-25 10:45:54.710 9922-11889/? I/FirebaseCrashlytics: Crashlytics Reports Endpoint upload complete: 5EEB8B0E0397-0001-5E2D-51D8468E4E93

So guess it was something cached in the Android build.

Still need to fix NDK crash reporting before merging to master & releasing...

Roshankd1 commented 3 years ago

@dpa99c Hi Dave, thank you for the update on Android, I was wandering if you'd know something regarding this error I am seeing in iOS after update. I have already tried importing GoogleServices-Info.plist again but no luck.

xx[4278:1163883] 6.23.0 - [Firebase/Installations][I-FIS002003] Firebase Installation registration failed for app with name: __FIRAPP_DEFAULT, error: The server responded with an error:

dpa99c commented 3 years ago

@Roshankd1 looking at the Firebase iOS SDK source code it appears this error is related to the project configuration. There's a similar report here. I'm not seeing this error on iOS and I don't believe the Firebase Crashyltics changes are related to it. So it is likely specific to your Firebase project configuration.

Roshankd1 commented 3 years ago

@dpa99c thank you I thought so as well and have been battling since yesterday trying to see what's missing or excess after the update :D I will keep trying! Good day :)

dpa99c commented 3 years ago

This functionality has been released in a new major version: cordova-plugin-firebasex@10.0.0

Roshankd1 commented 3 years ago

@dpa99c Hey Dave, finally able to fix my firebase config errors but still seeing a problem with Android.

I've tested in both release/debug environment still getting this error:

polyfills-es2015.js:3657 Unhandled Promise rejection: Cannot set Crashlytics user ID - Crashlytics collection is disabled ; Zone: ; Task: null ; Value: Cannot set Crashlytics user ID - Crashlytics collection is disabled undefined

dpa99c commented 3 years ago

@Roshankd1 looks like there's a regression on this line - it should not be a negative condition.

dpa99c commented 3 years ago

Just pushed a commit to master which should fix it.

Roshankd1 commented 3 years ago

@dpa99c Amazing thank you! Quick one, how are you testing crash on iOS? I'd imagine the with firebaseX wrapper right?

I am not able to see crash report pushed in Console(probably something to do with my crash test code??)

I used firebase.sendCrash();

Here is my log: 2020-06-29 18:23:10.577854+0200 XX[5088:1455022] AAA, simulate crash called Assertion failed: (NO), function -[FirebasePlugin sendCrash:], file /Users/{}/app/platforms/iOS/XX/Plugins/cordova-plugin-firebasex/FirebasePlugin.m, line 1109.

globules-io commented 3 years ago

Having this issue here, seems related? Please let me know if you'd like me to open a new ticket.. iOS only.

2020-07-02 17:23:08.501358-0400 MyApp[7438:287952] FirebasePlugin[native] LOG: GoogleService-Info.plist found, setup: [FIRApp configureWithOptions]
2020-07-02 17:23:08.534887-0400 MyApp[7438:287952] [Firebase/Crashlytics] Version 4.2.0
2020-07-02 17:23:08.588828-0400 MyApp[7438:288206] _hasPermission: YES
2020-07-02 17:23:08.596131-0400 MyApp[7438:287952] FirebasePlugin[native] LOG: Enter foreground: FCM direct channel = false
2020-07-02 17:23:08.647651-0400 MyApp[7438:287952] FirebasePlugin[native] LOG: didReceiveRegistrationToken: fdiIC7F0iE9htThzfXgTkK:APA91bFW6vKQxlewEYgawJCoUe2iFC0ZE6LDoFeheD82Z4jn8PgZRKQAQ-c0_io9_5klWcgo_70W7yESbSuOZ0J4WYEjtdEjUt4OXY6a0gSukKPvMH-d_g3aACcWb-yUyAjYw3iDenob
2020-07-02 17:23:08.651933-0400 MyApp[7438:287952] FirebasePlugin[native] LOG: tokenRefreshNotification: fdiIC7F0iE9htThzfXgTkK:APA91bFW6vKQxlewEYgawJCoUe2iFC0ZE6LDoFeheD82Z4jn8PgZRKQAQ-c0_io9_5klWcgo_70W7yESbSuOZ0J4WYEjtdEjUt4OXY6a0gSukKPvMH-d_g3aACcWb-yUyAjYw3iDenob
2020-07-02 17:23:08.662557-0400 MyApp[7438:287952] FirebasePlugin[native] LOG: didRegisterForRemoteNotificationsWithDeviceToken: {length = 32, bytes = 0x6a84cbcb a08c579b 3bce0f7d d9a11c8d ... 22dc9f7e 30a58369 }
2020-07-02 17:23:27.696493-0400 MyApp[7438:288218] 6.27.0 - [Firebase/Core][I-COR000003] The default Firebase app has not yet been configured. Add `[FIRApp configure];` (`FirebaseApp.configure()` in Swift) to your application initialization. Read more: https://goo.gl/ctyzm8.
2020-07-02 17:23:27.710147-0400 MyApp[7438:288218] Task <A7F943B7-A08A-4EB8-BEF7-3CF14F6C639A>.<1> finished with error [-1001] Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x2827e3c00 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=https://firebase-settings.crashlytics.com/spi/v2/platforms/ios/gmp/1:108937435448:ios:af98389fe95e17c0/settings?build_version=1.0.5&display_version=1.0.5&instance=931a65e2738db3a8159a67cf59c1780e904c6dab&source=1, NSErrorFailingURLKey=https://firebase-settings.crashlytics.com/spi/v2/platforms/ios/gmp/1:108937435448:ios:af98389fe95e17c0/settings?build_version=1.0.5&display_version=1.0.5&instance=931a65e2738db3a8159a67cf59c1780e904c6dab&source=1, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.}
2020-07-02 17:23:27.717644-0400 MyApp[7438:288279] Task <A7F943B7-A08A-4EB8-BEF7-3CF14F6C639A>.<1> HTTP load failed, 0/0 bytes (error code: -999 [1:89])
2020-07-02 17:23:32.566535-0400 MyApp[7438:288281] GoogleTagManager warning: No default container found. Container needs to be added to a container folder and added to the target.
2020-07-02 17:23:32.567314-0400 MyApp[7438:288217] 6.27.0 - [Firebase/Messaging][I-FCM001000] FIRMessaging Remote Notifications proxy enabled, will swizzle remote notification receiver handlers. If you'd prefer to manually integrate Firebase Messaging, add "FirebaseAppDelegateProxyEnabled" to your Info.plist, and set it to NO. Follow the instructions at:
https://firebase.google.com/docs/cloud-messaging/ios/client#method_swizzling_in_firebase_messaging
to ensure proper integration.
2020-07-02 17:23:32.636284-0400 MyApp[7438:288273] 6.27.0 - [Firebase/Crashlytics][I-CLS000000] Failed to download settings Error Domain=FIRCLSNetworkError Code=-5 "(null)" UserInfo={status_code=404, type=2, request_id=, content_type=text/html; charset=utf-8}
2020-07-02 17:23:32.637210-0400 MyApp[7438:288273] 6.27.0 - [Firebase/Analytics][I-ACS031025] Analytics screen reporting is enabled. Call +[FIRAnalytics setScreenName:setScreenClass:] to set the screen name or override the default screen class name. To disable screen reporting, set the flag FirebaseScreenReportingEnabled to NO (boolean) in the Info.plist
2020-07-02 17:23:32.642002-0400 MyApp[7438:288217] 6.27.0 - [Firebase/Analytics][I-ACS800023] No pending snapshot to activate. SDK name: app_measurement
2020-07-02 17:23:32.642887-0400 MyApp[7438:288217] 6.27.0 - [Firebase/Analytics][I-ACS023007] Analytics v.60601000 started
2020-07-02 17:23:32.643704-0400 MyApp[7438:288217] 6.27.0 - [Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see http://goo.gl/RfcP7r)
2020-07-02 17:23:32.683151-0400 MyApp[7438:288201] [] nw_connection_copy_protocol_metadata [C5] Client called nw_connection_copy_protocol_metadata on unconnected nw_connection
2020-07-02 17:23:32.683224-0400 MyApp[7438:288201] [] nw_connection_copy_protocol_metadata [C5] Client called nw_connection_copy_protocol_metadata on unconnected nw_connection
2020-07-02 17:23:32.683260-0400 MyApp[7438:288201] [] nw_connection_copy_connected_local_endpoint [C5] Client called nw_connection_copy_connected_local_endpoint on unconnected nw_connection
2020-07-02 17:23:32.685051-0400 MyApp[7438:288201] [] nw_connection_copy_connected_remote_endpoint [C5] Client called nw_connection_copy_connected_remote_endpoint on unconnected nw_connection
2020-07-02 17:23:32.685672-0400 MyApp[7438:288201] [] nw_connection_copy_connected_path [C5] Client called nw_connection_copy_connected_path on unconnected nw_connection
2020-07-02 17:23:32.685737-0400 MyApp[7438:288201] Connection 5: unable to determine interface type without an established connection
2020-07-02 17:23:32.686021-0400 MyApp[7438:288201] Connection 5: unable to determine interface classification without an established connection
2020-07-02 17:23:32.686578-0400 MyApp[7438:288201] [] nw_connection_copy_metadata [C5] Client called nw_connection_copy_metadata on unconnected nw_connection
2020-07-02 17:23:32.686616-0400 MyApp[7438:288201] Connection 5: unable to determine interface type without an established connection
2020-07-02 17:23:32.687505-0400 MyApp[7438:288201] Connection 5: unable to determine interface type without an established connection
2020-07-02 17:23:32.691445-0400 MyApp[7438:288217] 6.27.0 - [Firebase/InAppMessaging][I-IAM130004] Failed restful api request to fetch in-app messages: seeing http status code as 403 with body as {
  "error": {
    "code": 403,
    "message": "Firebase In-App Messaging API has not been used in project xxxxxxxx before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/firebaseinappmessaging.googleapis.com/overview?project=xxxxxxxx  then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.Help",
        "links": [
          {
            "description": "Google developers console API activation",
            "url": "https://console.developers.google.com/apis/api/firebaseinappmessaging.googleapis.com/overview?project=xxxxxxxx "
          }
        ]
      }
    ]
  }
}
2020-07-02 17:23:32.692232-0400 MyApp[7438:288217] 6.27.0 - [Firebase/InAppMessaging][I-IAM700002] Error happened during message fetching Error Domain=NSURLErrorDomain Code=403 "(null)"
2020-07-02 17:23:32.692559-0400 MyApp[7438:288217] 6.27.0 - [Firebase/Analytics][I-ACS023013] Analytics collection disabled
2020-07-02 17:23:32.701691-0400 MyApp[7438:288271] registerForRemoteNotifications
2020-07-02 17:23:32.701762-0400 MyApp[7438:288271] _hasPermission: YES
2020-07-02 17:23:32.711547-0400 MyApp[7438:287952] grantPermission
2020-07-02 17:23:32.714219-0400 MyApp[7438:288271] registerForRemoteNotifications
2020-07-02 17:23:32.714284-0400 MyApp[7438:288271] _hasPermission: YES
2020-07-02 17:26:01.187926-0400 MyApp[7438:288766] [general] Connection to daemon was invalidatedHavi
Roshankd1 commented 3 years ago

@globules-io The message seems pretty clear tbh, try to enable API as mentioned in the log message and also make sure you have updated your google-services.json file with latest API_KEY that you can retrieve from the fire base console. "api_key": [ { "current_key": "AIsaDeBekFJ4AK1ufU89jgn3afPtAcTGq2mFG1Z" } ]

This could be useful: https://stackoverflow.com/questions/58495985/firebase-403-permission-denied-firebaseerror-installations-requests-are-blo

Here is screenshot for reference to API_KEY that you will need to copy to replace your current_key value inside Google-Services.json

Screenshot 2020-07-03 at 13 47 07

globules-io commented 3 years ago

@Roshankd1 they are enabled, it is a iOS issue only, fixed it was somewhat fixed by uninstalling / reinstalling and redoing pods. Not sure what happened. Don't mind that comment anymore :)

fcamblor commented 3 years ago

@dpa99c First of all, thank you for handling this in the plugin.

Would it be possible to know what are the implications of not aligning our apps to cordova-plugin-firebasex >= 10.0 by November 15th ?

I stumbled upon this issue today, and the timing/effort to both :

... this all looks very tight to me.

That's why I'd need to know what's going to happen by Nov. 15th if I don't upgrade in time (now that the problem is fixed, I assume you should have an idea on the impacts) :

dpa99c commented 3 years ago

@fcamblor

  • Will I simply not get errors in crashlytics when firebasex will have some failures ? (silent errors)

My understanding is that after 15 Nov, any apps which haven't been migrated will stop receiving crash reports in Firebase. Even if you've updated the latest version of your app, users with old app versions installed will not have their crashes reported.

If you open the Crashlytics console in Firebase console for a project which has not yet been migrated you should see a warning like this: image

"Learn more" links to here

  • Will I have some features of firebasex that will not work ? (if yes, which ones ?)
  • Will some calls to firebasex plugin going to generate exceptions and break my app ?
  • Will my whole app not run at all ? (because of some kind of firebasex bootstrapping error due to deprecated backend)

The rest of the Firebase plugin functionality should work fine. Your app will continue to run and function as it does currently, but any crash reports sent via Fabric Crashlytics will be sent to a backend endpoint which will no longer accept them. The Crashlytics crash report upload is carried out internally by the Firebase SDK at app startup - if it fails, it won't affect your app functionality, you will probably just see an error in the Android Logcat/iOS Xcode console log output.

  • Are iOS apps concerned by the change ?

Both iOS and Android apps are affected.

fcamblor commented 3 years ago

@dpa99c thanks for your (very) quick feedback, as always you're providing insightful answers and I really appreciate it.

If I summarize, it looks like if I was not using Crashlytics before (it's my case) then I shouldn't be impacted.

I will cross fingers the exception raised by firebase internals when trying to reach the shutted down endpoint will not be caught by my general-purpose exception handler (my general-purpose exception handler is showing an error popup to end users) and will rather be caught and handled by firebase internally and silently.

That's one of my fears, and I assume it will be complicated to know the answer to this question before Nov 15th :(

tomavic commented 3 years ago

Hello @dpa99c Is there is any setting to disable crashlytics or how to bypass it cause I am getting android build errors when I am using it with capacitor. I don't need crashlytics and I can't find a way to disable it in this plugin's methods.

FYI the android build error is

Caused by: org.gradle.api.GradleException: Applying the Firebase Crashlytics plugin to a library project is unsupported. It should only be applied to the application module of your project to enable automatic upload of obfuscation mapping files for your application.

I am using latest version of everything 🗡️

fcamblor commented 3 years ago

@tomavic not sure if this will solve your build time issue (it looks more like a runtime workaround) but you can a look at this section of the doc (it allows to disable crashlytics at startup)

tomavic commented 3 years ago

@fcamblor yes i can do this when I am using cordova, but i am using capacitor. And the way to use cordova with capacitor is only install plugin without specifying variables.

Do you know how to set these variables the right way?

fcamblor commented 3 years ago

@tomavic I'm sorry I don't have knowledge into Capacitor yet :(

tomavic commented 3 years ago

@fcamblor me too 😔

I don't have any experience with capacitor. I was using cordova for the past time, and turned to capacitor because of firebase plugins issues. And AGAIN I faced it too! What an epic