From efeb24d168d40ea638b9f63e63f9fc290d889fdc Mon Sep 17 00:00:00 2001 From: Chris Bianca Date: Wed, 6 Dec 2017 17:25:17 +0000 Subject: [PATCH] [crashlytics] Add first version of crashlytics functionality --- android/build.gradle | 7 ++ .../crashlytics/RNFirebaseCrashlytics.java | 65 ++++++++++++++++ .../RNFirebaseCrashlyticsPackage.java | 39 ++++++++++ ios/RNFirebase.xcodeproj/project.pbxproj | 22 ++++++ .../crashlytics/RNFirebaseCrashlytics.h | 19 +++++ .../crashlytics/RNFirebaseCrashlytics.m | 47 +++++++++++ lib/modules/core/firebase-app.js | 6 ++ lib/modules/core/firebase.js | 6 ++ lib/modules/fabric/crashlytics/index.js | 77 +++++++++++++++++++ lib/types/index.js | 17 +++- tests/android/app/build.gradle | 4 + .../MainApplication.java | 2 + tests/android/build.gradle | 6 +- tests/ios/Podfile | 3 +- tests/ios/Podfile.lock | 13 +++- .../project.pbxproj | 17 +++- .../src/tests/crashlytics/crashlyticsTests.js | 52 +++++++++++++ tests/src/tests/crashlytics/index.js | 10 +++ tests/src/tests/index.js | 2 + 19 files changed, 406 insertions(+), 8 deletions(-) create mode 100644 android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlytics.java create mode 100644 android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlyticsPackage.java create mode 100644 ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.h create mode 100644 ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.m create mode 100644 lib/modules/fabric/crashlytics/index.js create mode 100644 tests/src/tests/crashlytics/crashlyticsTests.js create mode 100644 tests/src/tests/crashlytics/index.js diff --git a/android/build.gradle b/android/build.gradle index adf070f2..eb0e53c3 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -2,9 +2,13 @@ buildscript { ext.firebaseVersion = '11.4.2' repositories { jcenter() + maven { + url 'https://maven.fabric.io/public' + } } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' + classpath 'io.fabric.tools:gradle:1.24.4' } } @@ -91,4 +95,7 @@ dependencies { compile "com.google.firebase:firebase-ads:$firebaseVersion" compile "com.google.firebase:firebase-firestore:$firebaseVersion" compile "com.google.firebase:firebase-invites:$firebaseVersion" + compile('com.crashlytics.sdk.android:crashlytics:2.7.1@aar') { + transitive = true + } } diff --git a/android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlytics.java b/android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlytics.java new file mode 100644 index 00000000..f70a4732 --- /dev/null +++ b/android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlytics.java @@ -0,0 +1,65 @@ +package io.invertase.firebase.fabric.crashlytics; + +import android.util.Log; + +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; + +import com.crashlytics.android.Crashlytics; + + +public class RNFirebaseCrashlytics extends ReactContextBaseJavaModule { + + private static final String TAG = "RNFirebaseCrashlytics"; + + public RNFirebaseCrashlytics(ReactApplicationContext reactContext) { + super(reactContext); + Log.d(TAG, "New instance"); + } + + @Override + public String getName() { + return TAG; + } + + @ReactMethod + public void crash() { + Crashlytics.getInstance().crash(); + } + + @ReactMethod + public void log(final String message) { + Crashlytics.log(message); + } + + @ReactMethod + public void recordError(final int code, final String domain) { + Crashlytics.logException(new Exception(code + ": " + domain)); + } + + @ReactMethod + public void setBoolValue(final String key, final boolean boolValue) { + Crashlytics.setBool(key, boolValue); + } + + @ReactMethod + public void setFloatValue(final String key, final float floatValue) { + Crashlytics.setFloat(key, floatValue); + } + + @ReactMethod + public void setIntValue(final String key, final int intValue) { + Crashlytics.setInt(key, intValue); + } + + @ReactMethod + public void setStringValue(final String key, final String stringValue) { + Crashlytics.setString(key, stringValue); + } + + @ReactMethod + public void setUserIdentifier(String userId) { + Crashlytics.setUserIdentifier(userId); + } +} diff --git a/android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlyticsPackage.java b/android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlyticsPackage.java new file mode 100644 index 00000000..404f722a --- /dev/null +++ b/android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlyticsPackage.java @@ -0,0 +1,39 @@ +package io.invertase.firebase.fabric.crashlytics; + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.JavaScriptModule; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.UIManagerModule; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@SuppressWarnings("unused") +public class RNFirebaseCrashlyticsPackage implements ReactPackage { + public RNFirebaseCrashlyticsPackage() { + } + + /** + * @param reactContext react application context that can be used to create modules + * @return list of native modules to register with the newly created catalyst instance + */ + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + modules.add(new RNFirebaseCrashlytics(reactContext)); + + return modules; + } + + /** + * @param reactContext + * @return a list of view managers that should be registered with {@link UIManagerModule} + */ + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } +} diff --git a/ios/RNFirebase.xcodeproj/project.pbxproj b/ios/RNFirebase.xcodeproj/project.pbxproj index 9fba5805..cb5b930a 100644 --- a/ios/RNFirebase.xcodeproj/project.pbxproj +++ b/ios/RNFirebase.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 8323CF071F6FBD870071420B /* NativeExpressComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323CF011F6FBD870071420B /* NativeExpressComponent.m */; }; 8323CF081F6FBD870071420B /* RNFirebaseAdMobBannerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323CF031F6FBD870071420B /* RNFirebaseAdMobBannerManager.m */; }; 8323CF091F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323CF051F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m */; }; + 833693131FD824EF00AA806B /* RNFirebaseCrashlytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 833693121FD824EF00AA806B /* RNFirebaseCrashlytics.m */; }; 8376F7141F7C149100D45A85 /* RNFirebaseFirestoreDocumentReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F70E1F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.m */; }; 8376F7151F7C149100D45A85 /* RNFirebaseFirestore.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F7101F7C149000D45A85 /* RNFirebaseFirestore.m */; }; 8376F7161F7C149100D45A85 /* RNFirebaseFirestoreCollectionReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F7111F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.m */; }; @@ -57,6 +58,8 @@ 8323CF031F6FBD870071420B /* RNFirebaseAdMobBannerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMobBannerManager.m; sourceTree = ""; }; 8323CF041F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMobNativeExpressManager.h; sourceTree = ""; }; 8323CF051F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMobNativeExpressManager.m; sourceTree = ""; }; + 833693111FD824EF00AA806B /* RNFirebaseCrashlytics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNFirebaseCrashlytics.h; path = RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.h; sourceTree = SOURCE_ROOT; }; + 833693121FD824EF00AA806B /* RNFirebaseCrashlytics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNFirebaseCrashlytics.m; path = RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.m; sourceTree = SOURCE_ROOT; }; 8376F70E1F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseFirestoreDocumentReference.m; sourceTree = ""; }; 8376F70F1F7C149000D45A85 /* RNFirebaseFirestore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseFirestore.h; sourceTree = ""; }; 8376F7101F7C149000D45A85 /* RNFirebaseFirestore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseFirestore.m; sourceTree = ""; }; @@ -124,6 +127,7 @@ 58B511D21A9E6C8500147676 = { isa = PBXGroup; children = ( + 8336930F1FD80DE800AA806B /* fabric */, BA84AE541FA9E59800E79390 /* storage */, 17AF4F681F59CDBF00C02336 /* links */, 839D914D1EF3E20A0077C7C8 /* admob */, @@ -144,6 +148,23 @@ ); sourceTree = ""; }; + 8336930F1FD80DE800AA806B /* fabric */ = { + isa = PBXGroup; + children = ( + 833693101FD80DF500AA806B /* crashlytics */, + ); + path = fabric; + sourceTree = ""; + }; + 833693101FD80DF500AA806B /* crashlytics */ = { + isa = PBXGroup; + children = ( + 833693111FD824EF00AA806B /* RNFirebaseCrashlytics.h */, + 833693121FD824EF00AA806B /* RNFirebaseCrashlytics.m */, + ); + path = crashlytics; + sourceTree = ""; + }; 8376F70D1F7C141500D45A85 /* firestore */ = { isa = PBXGroup; children = ( @@ -328,6 +349,7 @@ 8376F7141F7C149100D45A85 /* RNFirebaseFirestoreDocumentReference.m in Sources */, 839D916F1EF3E20B0077C7C8 /* RNFirebaseAnalytics.m in Sources */, 839D91711EF3E20B0077C7C8 /* RNFirebaseRemoteConfig.m in Sources */, + 833693131FD824EF00AA806B /* RNFirebaseCrashlytics.m in Sources */, D950369E1D19C77400F7094D /* RNFirebase.m in Sources */, 839D91731EF3E20B0077C7C8 /* RNFirebaseDatabase.m in Sources */, BA84AE571FA9E59800E79390 /* RNFirebaseStorage.m in Sources */, diff --git a/ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.h b/ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.h new file mode 100644 index 00000000..c529237a --- /dev/null +++ b/ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.h @@ -0,0 +1,19 @@ +#ifndef RNFirebaseCrashlytics_h +#define RNFirebaseCrashlytics_h +#import + +#if __has_include() +#import + +@interface RNFirebaseCrashlytics : NSObject { + +} + +@end + +#else +@interface RNFirebaseCrashlytics : NSObject +@end +#endif + +#endif diff --git a/ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.m b/ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.m new file mode 100644 index 00000000..393f77a1 --- /dev/null +++ b/ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.m @@ -0,0 +1,47 @@ +#import "RNFirebaseCrashlytics.h" + +#if __has_include() +#import + +@implementation RNFirebaseCrashlytics +RCT_EXPORT_MODULE(); + +RCT_EXPORT_METHOD(crash) { + [[Crashlytics sharedInstance] crash]; +} + +RCT_EXPORT_METHOD(log:(NSString *)message) { + CLS_LOG(@"%@", message); +} + +RCT_EXPORT_METHOD(recordError:(nonnull NSNumber *)code domain:(NSString *)domain) { + NSError *error = [NSError errorWithDomain:domain code:[code integerValue] userInfo:nil]; + [CrashlyticsKit recordError:error]; +} + +RCT_EXPORT_METHOD(setBoolValue:(NSString *)key boolValue:(BOOL *)boolValue) { + [CrashlyticsKit setBoolValue:boolValue forKey:key]; +} + +RCT_EXPORT_METHOD(setFloatValue:(NSString *)key floatValue:(nonnull NSNumber *)floatValue) { + [CrashlyticsKit setFloatValue:[floatValue floatValue] forKey:key]; +} + +RCT_EXPORT_METHOD(setIntValue:(NSString *)key intValue:(nonnull NSNumber *)intValue) { + [CrashlyticsKit setIntValue:[intValue integerValue] forKey:key]; +} + +RCT_EXPORT_METHOD(setStringValue:(NSString *)key stringValue:(NSString *)stringValue) { + [CrashlyticsKit setObjectValue:stringValue forKey:key]; +} + +RCT_EXPORT_METHOD(setUserIdentifier:(NSString *)userId) { + [CrashlyticsKit setUserIdentifier:userId]; +} + +@end + +#else +@implementation RNFirebaseCrashlytics +@end +#endif diff --git a/lib/modules/core/firebase-app.js b/lib/modules/core/firebase-app.js index a582385b..686a0bed 100644 --- a/lib/modules/core/firebase-app.js +++ b/lib/modules/core/firebase-app.js @@ -11,6 +11,7 @@ import Auth, { statics as AuthStatics } from '../auth'; import Analytics, { statics as AnalyticsStatics } from '../analytics'; import Config, { statics as ConfigStatics } from '../config'; import Crash, { statics as CrashStatics } from '../crash'; +import Crashlytics, { statics as CrashlyticsStatics } from '../fabric/crashlytics'; import Database, { statics as DatabaseStatics } from '../database'; import Firestore, { statics as FirestoreStatics } from '../firestore'; import Links, { statics as LinksStatics } from '../links'; @@ -26,6 +27,7 @@ import type { ConfigModule, CrashModule, DatabaseModule, + FabricModule, FirebaseModule, FirebaseModuleAndStatics, FirebaseOptions, @@ -54,6 +56,7 @@ export default class FirebaseApp { config: ConfigModule; crash: CrashModule; database: DatabaseModule; + fabric: FabricModule; firestore: FirestoreModule; links: LinksModule; messaging: MessagingModule; @@ -77,6 +80,9 @@ export default class FirebaseApp { this.config = this._staticsOrModuleInstance(ConfigStatics, Config); this.crash = this._staticsOrModuleInstance(CrashStatics, Crash); this.database = this._staticsOrModuleInstance(DatabaseStatics, Database); + this.fabric = { + crashlytics: this._staticsOrModuleInstance(CrashlyticsStatics, Crashlytics), + }; this.firestore = this._staticsOrModuleInstance(FirestoreStatics, Firestore); this.links = this._staticsOrModuleInstance(LinksStatics, Links); this.messaging = this._staticsOrModuleInstance(MessagingStatics, Messaging); diff --git a/lib/modules/core/firebase.js b/lib/modules/core/firebase.js index 37e055c6..cbe83b90 100644 --- a/lib/modules/core/firebase.js +++ b/lib/modules/core/firebase.js @@ -14,6 +14,7 @@ import Auth, { statics as AuthStatics } from '../auth'; import Analytics, { statics as AnalyticsStatics } from '../analytics'; import Config, { statics as ConfigStatics } from '../config'; import Crash, { statics as CrashStatics } from '../crash'; +import Crashlytics, { statics as CrashlyticsStatics } from '../fabric/crashlytics'; import Database, { statics as DatabaseStatics } from '../database'; import Firestore, { statics as FirestoreStatics } from '../firestore'; import Links, { statics as LinksStatics } from '../links'; @@ -29,6 +30,7 @@ import type { ConfigModule, CrashModule, DatabaseModule, + FabricModule, FirebaseModule, FirebaseModuleAndStatics, FirebaseOptions, @@ -52,6 +54,7 @@ class FirebaseCore { config: ConfigModule; crash: CrashModule; database: DatabaseModule; + fabric: FabricModule; firestore: FirestoreModule; links: LinksModule; messaging: MessagingModule; @@ -76,6 +79,9 @@ class FirebaseCore { this.config = this._appNamespaceOrStatics(ConfigStatics, Config); this.crash = this._appNamespaceOrStatics(CrashStatics, Crash); this.database = this._appNamespaceOrStatics(DatabaseStatics, Database); + this.fabric = { + crashlytics: this._appNamespaceOrStatics(CrashlyticsStatics, Crashlytics), + }; this.firestore = this._appNamespaceOrStatics(FirestoreStatics, Firestore); this.links = this._appNamespaceOrStatics(LinksStatics, Links); this.messaging = this._appNamespaceOrStatics(MessagingStatics, Messaging); diff --git a/lib/modules/fabric/crashlytics/index.js b/lib/modules/fabric/crashlytics/index.js new file mode 100644 index 00000000..6ab1d9f9 --- /dev/null +++ b/lib/modules/fabric/crashlytics/index.js @@ -0,0 +1,77 @@ +/** + * @flow + * Crash Reporting representation wrapper + */ +import ModuleBase from '../../../utils/ModuleBase'; + +import type FirebaseApp from '../../core/firebase-app'; + +export default class Crashlytics extends ModuleBase { + static _NAMESPACE = 'crashlytics'; + static _NATIVE_MODULE = 'RNFirebaseCrashlytics'; + + constructor(firebaseApp: FirebaseApp, options: Object = {}) { + super(firebaseApp, options); + } + + /** + * Forces a crash. Useful for testing your application is set up correctly. + */ + crash(): void { + this._native.crash(); + } + + /** + * Logs a message that will appear in any subsequent crash reports. + * @param {string} message + */ + log(message: string): void { + this._native.log(message); + } + + /** + * Logs a non fatal exception. + * @param {string} code + * @param {string} message + */ + recordError(code: number, message: string): void { + this._native.recordError(code, message); + } + + /** + * Set a boolean value to show alongside any subsequent crash reports. + */ + setBoolValue(key: string, value: boolean): void { + this._native.setBoolValue(key, value); + } + + /** + * Set a float value to show alongside any subsequent crash reports. + */ + setFloatValue(key: string, value: number): void { + this._native.setFloatValue(key, value); + } + + /** + * Set an integer value to show alongside any subsequent crash reports. + */ + setIntValue(key: string, value: number): void { + this._native.setIntValue(key, value); + } + + /** + * Set a string value to show alongside any subsequent crash reports. + */ + setStringValue(key: string, value: string): void { + this._native.setStringValue(key, value); + } + + /** + * Set the user ID to show alongside any subsequent crash reports. + */ + setUserIdentifier(userId: string): void { + this._native.setUserIdentifier(userId); + } +} + +export const statics = {}; diff --git a/lib/types/index.js b/lib/types/index.js index 48fb199d..deded1cb 100644 --- a/lib/types/index.js +++ b/lib/types/index.js @@ -9,6 +9,8 @@ import type Config from '../modules/config'; import { typeof statics as ConfigStatics } from '../modules/config'; import type Crash from '../modules/crash'; import { typeof statics as CrashStatics } from '../modules/crash'; +import type Crashlytics from '../modules/fabric/crashlytics'; +import { typeof statics as CrashlyticsStatics } from '../modules/fabric/crashlytics'; import type Database from '../modules/database'; import { typeof statics as DatabaseStatics } from '../modules/database'; import type Firestore from '../modules/firestore'; @@ -38,8 +40,9 @@ export type FirebaseError = { export type FirebaseModule = $Subtype; -export type FirebaseModuleName = 'admob' | 'analytics' | 'auth' | 'config' | 'crash' | 'database' - | 'firestore' | 'links' | 'messaging' | 'perf' | 'storage' | 'utils'; +export type FirebaseModuleName = 'admob' | 'analytics' | 'auth' | 'config' | 'crash' + | 'crashlytics' | 'database' | 'firestore' | 'links' | 'messaging' | 'perf' | 'storage' + | 'utils'; export type FirebaseOptions = { apiKey: string, @@ -115,6 +118,16 @@ export type DatabaseModifier = { valueType?: string; } +/* Fabric types */ +export type CrashlyticsModule = { + (): Crashlytics, + nativeModuleExists: boolean, +} & CrashlyticsStatics; + +export type FabricModule = { + crashlytics: CrashlyticsModule, +} + /* Firestore types */ export type FirestoreModule = { diff --git a/tests/android/app/build.gradle b/tests/android/app/build.gradle index 83c93fac..3889b642 100644 --- a/tests/android/app/build.gradle +++ b/tests/android/app/build.gradle @@ -1,5 +1,6 @@ apply plugin: "com.android.application" apply plugin: "com.google.firebase.firebase-perf" +apply plugin: 'io.fabric' import com.android.build.OutputFile @@ -93,6 +94,9 @@ dependencies { compile "com.google.firebase:firebase-storage:$firebaseVersion" compile "com.google.firebase:firebase-firestore:$firebaseVersion" compile "com.google.firebase:firebase-invites:$firebaseVersion" + compile('com.crashlytics.sdk.android:crashlytics:2.7.1@aar') { + transitive = true + } compile "com.android.support:appcompat-v7:26.0.1" compile "com.facebook.react:react-native:+" // From node_modules } diff --git a/tests/android/app/src/main/java/com/reactnativefirebasedemo/MainApplication.java b/tests/android/app/src/main/java/com/reactnativefirebasedemo/MainApplication.java index e74da522..1385efd0 100644 --- a/tests/android/app/src/main/java/com/reactnativefirebasedemo/MainApplication.java +++ b/tests/android/app/src/main/java/com/reactnativefirebasedemo/MainApplication.java @@ -10,6 +10,7 @@ import io.invertase.firebase.auth.RNFirebaseAuthPackage; import io.invertase.firebase.config.RNFirebaseRemoteConfigPackage; import io.invertase.firebase.crash.RNFirebaseCrashPackage; import io.invertase.firebase.database.RNFirebaseDatabasePackage; +import io.invertase.firebase.fabric.crashlytics.RNFirebaseCrashlyticsPackage; import io.invertase.firebase.firestore.RNFirebaseFirestorePackage; import io.invertase.firebase.links.RNFirebaseLinksPackage; import io.invertase.firebase.messaging.RNFirebaseMessagingPackage; @@ -43,6 +44,7 @@ public class MainApplication extends Application implements ReactApplication { new RNFirebaseAuthPackage(), new RNFirebaseRemoteConfigPackage(), new RNFirebaseCrashPackage(), + new RNFirebaseCrashlyticsPackage(), new RNFirebaseDatabasePackage(), new RNFirebaseFirestorePackage(), new RNFirebaseLinksPackage(), diff --git a/tests/android/build.gradle b/tests/android/build.gradle index 32ba1492..2043c3f7 100644 --- a/tests/android/build.gradle +++ b/tests/android/build.gradle @@ -3,11 +3,15 @@ buildscript { repositories { jcenter() + maven { + url 'https://maven.fabric.io/public' + } } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' - classpath 'com.google.gms:google-services:3.1.1' + classpath 'com.google.gms:google-services:3.1.2' classpath 'com.google.firebase:firebase-plugins:1.1.1' + classpath 'io.fabric.tools:gradle:1.24.4' } } diff --git a/tests/ios/Podfile b/tests/ios/Podfile index d471bdd1..980cd7c7 100644 --- a/tests/ios/Podfile +++ b/tests/ios/Podfile @@ -30,7 +30,8 @@ target 'ReactNativeFirebaseDemo' do pod 'Firebase/RemoteConfig' pod 'Firebase/Storage' pod 'Firebase/Performance' - + pod 'Fabric', '~> 1.7.2' + pod 'Crashlytics', '~> 3.9.3' pod 'RNFirebase', :path => './../../' diff --git a/tests/ios/Podfile.lock b/tests/ios/Podfile.lock index 71d4438c..f140bddf 100644 --- a/tests/ios/Podfile.lock +++ b/tests/ios/Podfile.lock @@ -5,6 +5,9 @@ PODS: - BoringSSL/Implementation (9.0): - BoringSSL/Interface (= 9.0) - BoringSSL/Interface (9.0) + - Crashlytics (3.9.3): + - Fabric (~> 1.7.2) + - Fabric (1.7.2) - Firebase/AdMob (4.3.0): - Firebase/Core - Google-Mobile-Ads-SDK (= 7.24.1) @@ -150,11 +153,13 @@ PODS: - React/Core - React/fishhook - React/RCTBlob - - RNFirebase (3.1.1-alpha.11): + - RNFirebase (3.1.1): - React - yoga (0.49.1.React) DEPENDENCIES: + - Crashlytics (~> 3.9.3) + - Fabric (~> 1.7.2) - Firebase/AdMob - Firebase/Auth - Firebase/Core @@ -184,6 +189,8 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: BoringSSL: 19083b821ef3ae0f758fae15482e183003b1e265 + Crashlytics: dbb07d01876c171c5ccbdf7826410380189e452c + Fabric: 9cd6a848efcf1b8b07497e0b6a2e7d336353ba15 Firebase: 83283761a1ef6dc9846e03d08059f51421afbd65 FirebaseAnalytics: 722b53c7b32bfc7806b06e0093a2f5180d4f2c5a FirebaseAuth: d7f047fbeab98062b98ea933b8d934e0fb1190e2 @@ -208,9 +215,9 @@ SPEC CHECKSUMS: nanopb: 5601e6bca2dbf1ed831b519092ec110f66982ca3 Protobuf: 03eef2ee0b674770735cf79d9c4d3659cf6908e8 React: cf892fb84b7d06bf5fea7f328e554c6dcabe85ee - RNFirebase: e959075eb2f348c3586cd92973543b80e373b29c + RNFirebase: 30522211772f22affff6f3a61981110852d2668b yoga: 3abf02d6d9aeeb139b4c930eb1367feae690a35a -PODFILE CHECKSUM: b5674be55653f5dda937c8b794d0479900643d45 +PODFILE CHECKSUM: a5e2256012836120598e7daba7320d085400ecbb COCOAPODS: 1.2.1 diff --git a/tests/ios/ReactNativeFirebaseDemo.xcodeproj/project.pbxproj b/tests/ios/ReactNativeFirebaseDemo.xcodeproj/project.pbxproj index c1c8a35d..0c7128d5 100644 --- a/tests/ios/ReactNativeFirebaseDemo.xcodeproj/project.pbxproj +++ b/tests/ios/ReactNativeFirebaseDemo.xcodeproj/project.pbxproj @@ -636,6 +636,7 @@ 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, C015646CE8F8CB4B578CE178 /* [CP] Embed Pods Frameworks */, 6AE1012F46FF8A4D1D818A12 /* [CP] Copy Pods Resources */, + 8336933B1FD8559A00AA806B /* Fabric */, ); buildRules = ( ); @@ -1043,7 +1044,7 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-ReactNativeFirebaseDemo/Pods-ReactNativeFirebaseDemo-resources.sh", - "$PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle", + $PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle, ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -1054,6 +1055,20 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ReactNativeFirebaseDemo/Pods-ReactNativeFirebaseDemo-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 8336933B1FD8559A00AA806B /* Fabric */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = Fabric; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Fabric/run\""; + }; C015646CE8F8CB4B578CE178 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/tests/src/tests/crashlytics/crashlyticsTests.js b/tests/src/tests/crashlytics/crashlyticsTests.js new file mode 100644 index 00000000..0ab89822 --- /dev/null +++ b/tests/src/tests/crashlytics/crashlyticsTests.js @@ -0,0 +1,52 @@ +export default function addTests({ describe, it, firebase }) { + describe('Crashlytics', () => { + it('log: it should log without error', () => { + return new Promise((resolve) => { + firebase.native.fabric.crashlytics().log('Test log'); + resolve(); + }); + }); + + it('recordError: it should record an error without error', () => { + return new Promise((resolve) => { + firebase.native.fabric.crashlytics().recordError(1234, 'Test error'); + resolve(); + }); + }); + + it('setBoolValue: it should set a boolean value without error', () => { + return new Promise((resolve) => { + firebase.native.fabric.crashlytics().setBoolValue('boolKey', true); + resolve(); + }); + }); + + it('setFloatValue: it should set a float value without error', () => { + return new Promise((resolve) => { + firebase.native.fabric.crashlytics().setFloatValue('floatKey', 1.23); + resolve(); + }); + }); + + it('setIntValue: it should set an integer value without error', () => { + return new Promise((resolve) => { + firebase.native.fabric.crashlytics().setIntValue('intKey', 123); + resolve(); + }); + }); + + it('setStringValue: it should set a string value without error', () => { + return new Promise((resolve) => { + firebase.native.fabric.crashlytics().setStringValue('stringKey', 'test'); + resolve(); + }); + }); + + it('setUserIdentifier: it should set the user ID without error', () => { + return new Promise((resolve) => { + firebase.native.fabric.crashlytics().setUserIdentifier('1234'); + resolve(); + }); + }); + }); +} diff --git a/tests/src/tests/crashlytics/index.js b/tests/src/tests/crashlytics/index.js new file mode 100644 index 00000000..89f6a038 --- /dev/null +++ b/tests/src/tests/crashlytics/index.js @@ -0,0 +1,10 @@ +import firebase from '../../firebase'; +import TestSuite from '../../../lib/TestSuite'; +import crashlyticsTests from './crashlyticsTests'; + +const suite = new TestSuite('Crashlytics', 'firebase.fabric.crashlytics()', firebase); + +// bootstrap tests +suite.addTests(crashlyticsTests); + +export default suite; diff --git a/tests/src/tests/index.js b/tests/src/tests/index.js index 1dbf53c6..0522195b 100644 --- a/tests/src/tests/index.js +++ b/tests/src/tests/index.js @@ -1,6 +1,7 @@ import { setSuiteStatus, setTestStatus } from '../actions/TestActions'; import analytics from './analytics'; import crash from './crash'; +import crashlytics from './crashlytics'; import core from './core'; import database from './database'; import messaging from './messaging'; @@ -23,6 +24,7 @@ const testSuiteInstances = [ config, core, crash, + crashlytics, database, firestore, messaging,