From 77a09f5810f4c2c3e7117c31d1e610960fb526ec Mon Sep 17 00:00:00 2001 From: Chris Bianca Date: Fri, 10 Mar 2017 14:17:37 +0000 Subject: [PATCH] Add Firebase Crash Reporting for iOS and Android --- android/build.gradle | 2 +- .../invertase/firebase/RNFirebasePackage.java | 2 + .../firebase/crash/RNFirebaseCrash.java | 40 ++++++++++++++++++ ios/RNFirebase/RNFirebaseCrash.h | 12 ++++++ ios/RNFirebase/RNFirebaseCrash.m | 26 ++++++++++++ lib/firebase.js | 9 ++++ lib/modules/crash/index.js | 42 +++++++++++++++++++ 7 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 android/src/main/java/io/invertase/firebase/crash/RNFirebaseCrash.java create mode 100644 ios/RNFirebase/RNFirebaseCrash.h create mode 100644 ios/RNFirebase/RNFirebaseCrash.m create mode 100644 lib/modules/crash/index.js diff --git a/android/build.gradle b/android/build.gradle index bfec37c4..af712657 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -52,5 +52,5 @@ dependencies { compile 'com.google.firebase:firebase-database:10.2.0' compile 'com.google.firebase:firebase-storage:10.2.0' compile 'com.google.firebase:firebase-messaging:10.2.0' + compile 'com.google.firebase:firebase-crash:10.2.0' } - diff --git a/android/src/main/java/io/invertase/firebase/RNFirebasePackage.java b/android/src/main/java/io/invertase/firebase/RNFirebasePackage.java index 9eaf8dd5..be6c3b93 100644 --- a/android/src/main/java/io/invertase/firebase/RNFirebasePackage.java +++ b/android/src/main/java/io/invertase/firebase/RNFirebasePackage.java @@ -17,6 +17,7 @@ import io.invertase.firebase.auth.RNFirebaseAuth; import io.invertase.firebase.storage.RNFirebaseStorage; import io.invertase.firebase.database.RNFirebaseDatabase; import io.invertase.firebase.analytics.RNFirebaseAnalytics; +import io.invertase.firebase.crash.RNFirebaseCrash; import io.invertase.firebase.messaging.RNFirebaseMessaging; @SuppressWarnings("unused") @@ -39,6 +40,7 @@ public class RNFirebasePackage implements ReactPackage { modules.add(new RNFirebaseAnalytics(reactContext)); modules.add(new RNFirebaseStorage(reactContext)); modules.add(new RNFirebaseMessaging(reactContext)); + modules.add(new RNFirebaseCrash(reactContext)); return modules; } diff --git a/android/src/main/java/io/invertase/firebase/crash/RNFirebaseCrash.java b/android/src/main/java/io/invertase/firebase/crash/RNFirebaseCrash.java new file mode 100644 index 00000000..4165bc2a --- /dev/null +++ b/android/src/main/java/io/invertase/firebase/crash/RNFirebaseCrash.java @@ -0,0 +1,40 @@ +package io.invertase.firebase.crash; + +import android.util.Log; + +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; + +import com.google.firebase.crash.FirebaseCrash; + + +public class RNFirebaseCrash extends ReactContextBaseJavaModule { + + private static final String TAG = "RNFirebaseCrash"; + + public RNFirebaseCrash(ReactApplicationContext reactContext) { + super(reactContext); + Log.d(TAG, "New instance"); + } + + @Override + public String getName() { + return TAG; + } + + @ReactMethod + public void log(final String message) { + FirebaseCrash.log(message); + } + + @ReactMethod + public void logcat(final int level, final String tag, final String message) { + FirebaseCrash.logcat(level, tag, message); + } + + @ReactMethod + public void report(String message) { + FirebaseCrash.report(new Exception(message)); + } +} diff --git a/ios/RNFirebase/RNFirebaseCrash.h b/ios/RNFirebase/RNFirebaseCrash.h new file mode 100644 index 00000000..ed987c1c --- /dev/null +++ b/ios/RNFirebase/RNFirebaseCrash.h @@ -0,0 +1,12 @@ +#ifndef RNFirebaseCrash_h +#define RNFirebaseCrash_h + +#import "RCTBridgeModule.h" + +@interface RNFirebaseCrash : NSObject { + +} + +@end + +#endif diff --git a/ios/RNFirebase/RNFirebaseCrash.m b/ios/RNFirebase/RNFirebaseCrash.m new file mode 100644 index 00000000..e4618731 --- /dev/null +++ b/ios/RNFirebase/RNFirebaseCrash.m @@ -0,0 +1,26 @@ +#import "RNFirebaseCrash.h" +#import "Firebase.h" + +@implementation RNFirebaseCrash + +RCT_EXPORT_MODULE(RNFirebaseCrash); + +RCT_EXPORT_METHOD(log:(NSString *)message) +{ + FIRCrashLog(message); +} + +RCT_EXPORT_METHOD(logcat:(nonnull NSNumber *) level + tag:(NSString *) tag + message:(NSString *) message) +{ + FIRCrashLog(message); +} + +RCT_EXPORT_METHOD(report:(NSString *) message) +{ + FIRCrashLog(message); + assert(NO); +} + +@end diff --git a/lib/firebase.js b/lib/firebase.js index 5e1c28fd..d1a34e3c 100644 --- a/lib/firebase.js +++ b/lib/firebase.js @@ -14,6 +14,7 @@ import Storage from './modules/storage'; import Database from './modules/database'; import Messaging from './modules/messaging'; import Analytics from './modules/analytics'; +import Crash from './modules/crash'; let log; const instances = { default: null }; @@ -67,6 +68,7 @@ export default class Firebase extends Singleton { _constants: ?Object; _messaging: ?Object; _remoteConfig: ?Object; + _crash: ?Object; /** * Support web version of initApp. @@ -148,6 +150,13 @@ export default class Firebase extends Singleton { return this._messaging; } + crash() { + if (!this._crash) { + this._crash = new Crash(this); + } + return this._crash; + } + get apps(): Array { return Object.keys(instances); } diff --git a/lib/modules/crash/index.js b/lib/modules/crash/index.js new file mode 100644 index 00000000..9e60ca66 --- /dev/null +++ b/lib/modules/crash/index.js @@ -0,0 +1,42 @@ +// @flow +import { NativeModules } from 'react-native'; +import { Base } from './../base'; + +const FirebaseCrash = NativeModules.RNFirebaseCrash; + +export default class Analytics extends Base { + /** + * Logs a message that will appear in a subsequent crash report. + * @param {string} message + * @param params + */ + log(message: string): void { + FirebaseCrash.log(message); + } + + /** + * Logs a message that will appear in a subsequent crash report as well as in logcat. + * NOTE: Android only functionality. iOS will just log the message. + * @param {string} message + * @param {number} level + * @param {string} tag + */ + logcat(level: number, tag: string, message: string): void { + FirebaseCrash.logcat(level, tag, message); + } + + /** + * Generates a crash report for the given message. This method should be used for unexpected + * exceptions where recovery is not possible. + * NOTE: on iOS, this will cause the app to crash as it's the only way to ensure the exception + * gets sent to Firebase. Otherwise it just gets lost as a log message. + * @param {string} message + */ + report(message: string): void { + FirebaseCrash.report(message); + } + + get namespace(): string { + return 'firebase:crash'; + } +}