@react-native-firebase/crashlytics 23.8.0 → 23.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1146 -0
- package/RNFBCrashlytics.podspec +54 -0
- package/android/.editorconfig +10 -0
- package/android/build.gradle +102 -0
- package/android/lint.xml +5 -0
- package/android/settings.gradle +1 -0
- package/android/src/main/AndroidManifest.xml +15 -0
- package/android/src/main/java/io/invertase/firebase/crashlytics/Constants.java +29 -0
- package/android/src/main/java/io/invertase/firebase/crashlytics/JavaScriptError.java +28 -0
- package/android/src/main/java/io/invertase/firebase/crashlytics/ReactNativeFirebaseCrashlyticsInitProvider.java +130 -0
- package/android/src/main/java/io/invertase/firebase/crashlytics/ReactNativeFirebaseCrashlyticsModule.java +223 -0
- package/android/src/main/java/io/invertase/firebase/crashlytics/ReactNativeFirebaseCrashlyticsNativeHelper.java +18 -0
- package/android/src/main/java/io/invertase/firebase/crashlytics/ReactNativeFirebaseCrashlyticsPackage.java +41 -0
- package/android/src/main/java/io/invertase/firebase/crashlytics/UnhandledPromiseRejection.java +28 -0
- package/app.plugin.js +1 -0
- package/dist/commonjs/version.js +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/commonjs/lib/namespaced.d.ts +1 -1
- package/dist/typescript/commonjs/lib/version.d.ts +1 -1
- package/dist/typescript/module/lib/namespaced.d.ts +1 -1
- package/dist/typescript/module/lib/version.d.ts +1 -1
- package/ios/RNFBCrashlytics/RNFBCrashlyticsInitProvider.h +33 -0
- package/ios/RNFBCrashlytics/RNFBCrashlyticsInitProvider.m +142 -0
- package/ios/RNFBCrashlytics/RNFBCrashlyticsModule.h +24 -0
- package/ios/RNFBCrashlytics/RNFBCrashlyticsModule.m +248 -0
- package/ios/RNFBCrashlytics/RNFBCrashlyticsNativeHelper.h +29 -0
- package/ios/RNFBCrashlytics/RNFBCrashlyticsNativeHelper.m +36 -0
- package/ios/RNFBCrashlytics.xcodeproj/project.pbxproj +359 -0
- package/ios/RNFBCrashlytics.xcodeproj/xcshareddata/IDETemplateMacros.plist +24 -0
- package/ios_config.sh +25 -0
- package/lib/version.ts +1 -1
- package/package.json +5 -15
- package/plugin/build/android/applyPlugin.d.ts +6 -0
- package/plugin/build/android/applyPlugin.js +28 -0
- package/plugin/build/android/buildscriptDependency.d.ts +6 -0
- package/plugin/build/android/buildscriptDependency.js +29 -0
- package/plugin/build/android/constants.d.ts +3 -0
- package/plugin/build/android/constants.js +7 -0
- package/plugin/build/android/index.d.ts +3 -0
- package/plugin/build/android/index.js +7 -0
- package/plugin/build/index.d.ts +3 -0
- package/plugin/build/index.js +12 -0
- package/plugin/tsconfig.tsbuildinfo +1 -0
- package/react-native.config.js +35 -0
package/android/src/main/java/io/invertase/firebase/crashlytics/UnhandledPromiseRejection.java
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
package io.invertase.firebase.crashlytics;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* This class is purely cosmetic - to indicate on the Crashlytics console that it's an
|
|
22
|
+
* UnhandledPromiseRejection JS error rather than the generic `java.lang.Exception`.
|
|
23
|
+
*/
|
|
24
|
+
class UnhandledPromiseRejection extends Exception {
|
|
25
|
+
UnhandledPromiseRejection(String message) {
|
|
26
|
+
super(message);
|
|
27
|
+
}
|
|
28
|
+
}
|
package/app.plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./plugin/build');
|
package/dist/commonjs/version.js
CHANGED
package/dist/module/version.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Crashlytics, Statics } from './types/crashlytics';
|
|
2
2
|
import type { ReactNativeFirebase } from '@react-native-firebase/app';
|
|
3
|
-
export declare const SDK_VERSION = "23.8.
|
|
3
|
+
export declare const SDK_VERSION = "23.8.1";
|
|
4
4
|
type CrashlyticsNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp<Crashlytics, Statics> & {
|
|
5
5
|
crashlytics: ReactNativeFirebase.FirebaseModuleWithStaticsAndApp<Crashlytics, Statics>;
|
|
6
6
|
firebase: ReactNativeFirebase.Module;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "23.8.
|
|
1
|
+
export declare const version = "23.8.1";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Crashlytics, Statics } from './types/crashlytics';
|
|
2
2
|
import type { ReactNativeFirebase } from '@react-native-firebase/app';
|
|
3
|
-
export declare const SDK_VERSION = "23.8.
|
|
3
|
+
export declare const SDK_VERSION = "23.8.1";
|
|
4
4
|
type CrashlyticsNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp<Crashlytics, Statics> & {
|
|
5
5
|
crashlytics: ReactNativeFirebase.FirebaseModuleWithStaticsAndApp<Crashlytics, Statics>;
|
|
6
6
|
firebase: ReactNativeFirebase.Module;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "23.8.
|
|
1
|
+
export declare const version = "23.8.1";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#import <FirebaseCoreExtension/FIRLibrary.h>
|
|
19
|
+
#import <Foundation/Foundation.h>
|
|
20
|
+
|
|
21
|
+
@interface RNFBCrashlyticsInitProvider : NSObject <FIRLibrary>
|
|
22
|
+
|
|
23
|
+
+ (BOOL)isCrashlyticsCollectionEnabled;
|
|
24
|
+
|
|
25
|
+
+ (BOOL)isErrorGenerationOnJSCrashEnabled;
|
|
26
|
+
|
|
27
|
+
+ (BOOL)isCrashlyticsJavascriptExceptionHandlerChainingEnabled;
|
|
28
|
+
|
|
29
|
+
/// Returns one or more FIRComponents that will be registered in
|
|
30
|
+
/// FIRApp and participate in dependency resolution and injection.
|
|
31
|
+
+ (NSArray<FIRComponent *> *)componentsToRegister;
|
|
32
|
+
|
|
33
|
+
@end
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#import "RNFBCrashlyticsInitProvider.h"
|
|
19
|
+
#import <Firebase/Firebase.h>
|
|
20
|
+
#import <FirebaseCoreExtension/FIRAppInternal.h>
|
|
21
|
+
#import <FirebaseCoreExtension/FIRComponent.h>
|
|
22
|
+
#import <FirebaseCoreExtension/FIRComponentContainer.h>
|
|
23
|
+
#import <FirebaseCoreExtension/FIRComponentType.h>
|
|
24
|
+
#import <FirebaseCoreExtension/FIRLibrary.h>
|
|
25
|
+
#import <FirebaseCrashlytics/FIRCrashlytics.h>
|
|
26
|
+
#import "RNFBJSON.h"
|
|
27
|
+
#import "RNFBMeta.h"
|
|
28
|
+
#import "RNFBPreferences.h"
|
|
29
|
+
#import "RNFBSharedUtils.h"
|
|
30
|
+
#import "RNFBVersion.h"
|
|
31
|
+
|
|
32
|
+
NSString *const KEY_APP_DATA_COLLECTION_DEFAULT_ENABLED = @"app_data_collection_default_enabled";
|
|
33
|
+
NSString *const KEY_CRASHLYTICS_DEBUG_ENABLED = @"crashlytics_debug_enabled";
|
|
34
|
+
NSString *const KEY_CRASHLYTICS_AUTO_COLLECTION_ENABLED = @"crashlytics_auto_collection_enabled";
|
|
35
|
+
NSString *const KEY_CRASHLYTICS_IS_ERROR_GENERATION_ON_JS_CRASH_ENABLED =
|
|
36
|
+
@"crashlytics_is_error_generation_on_js_crash_enabled";
|
|
37
|
+
NSString *const KEY_CRASHLYTICS_JAVASCRIPT_EXCEPTION_HANDLER_CHAINING_ENABLED =
|
|
38
|
+
@"crashlytics_javascript_exception_handler_chaining_enabled";
|
|
39
|
+
|
|
40
|
+
/// Empty protocol to register this provider as a component with Core.
|
|
41
|
+
@protocol RNFBCrashlyticsInitProviderProtocol
|
|
42
|
+
@end
|
|
43
|
+
|
|
44
|
+
/// The name of the Crashlytics component in FirebaseCore's component system. Reference:
|
|
45
|
+
// https://github.com/firebase/firebase-ios-sdk/blob/main/Crashlytics/Crashlytics/FIRCrashlytics.m#L87-L89
|
|
46
|
+
@protocol FIRCrashlyticsInstanceProvider <NSObject>
|
|
47
|
+
@end
|
|
48
|
+
|
|
49
|
+
/// Privately conform to the protocol for component registration.
|
|
50
|
+
@interface RNFBCrashlyticsInitProvider () <RNFBCrashlyticsInitProviderProtocol, FIRLibrary>
|
|
51
|
+
@end
|
|
52
|
+
|
|
53
|
+
@implementation RNFBCrashlyticsInitProvider
|
|
54
|
+
|
|
55
|
+
+ (void)load {
|
|
56
|
+
[FIRApp registerInternalLibrary:self
|
|
57
|
+
withName:@"react-native-firebase-crashlytics"
|
|
58
|
+
withVersion:[RNFBVersionString copy]];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
+ (BOOL)isCrashlyticsCollectionEnabled {
|
|
62
|
+
#ifdef DEBUG
|
|
63
|
+
if (![RNFBSharedUtils getConfigBooleanValue:@"RNFBCrashlyticsInit"
|
|
64
|
+
key:KEY_CRASHLYTICS_DEBUG_ENABLED
|
|
65
|
+
defaultValue:NO]) {
|
|
66
|
+
DLog(@"RNFBCrashlyticsInit isCrashlyticsCollectionEnabled after checking %@: %d",
|
|
67
|
+
KEY_CRASHLYTICS_DEBUG_ENABLED, FALSE);
|
|
68
|
+
return FALSE;
|
|
69
|
+
}
|
|
70
|
+
#endif
|
|
71
|
+
|
|
72
|
+
if ([RNFBSharedUtils configContains:KEY_CRASHLYTICS_AUTO_COLLECTION_ENABLED]) {
|
|
73
|
+
return [RNFBSharedUtils getConfigBooleanValue:@"RNFBCrashlyticsInit"
|
|
74
|
+
key:KEY_CRASHLYTICS_AUTO_COLLECTION_ENABLED
|
|
75
|
+
defaultValue:YES];
|
|
76
|
+
}
|
|
77
|
+
DLog(@"RNFBCrashlyticsInit specific key %@ not set, falling back to general key %@ with default "
|
|
78
|
+
@"%d if it does not exist.",
|
|
79
|
+
KEY_CRASHLYTICS_AUTO_COLLECTION_ENABLED, KEY_APP_DATA_COLLECTION_DEFAULT_ENABLED, YES);
|
|
80
|
+
return [RNFBSharedUtils getConfigBooleanValue:@"RNFBCrashlyticsInit"
|
|
81
|
+
key:KEY_APP_DATA_COLLECTION_DEFAULT_ENABLED
|
|
82
|
+
defaultValue:YES];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
+ (BOOL)isErrorGenerationOnJSCrashEnabled {
|
|
86
|
+
return
|
|
87
|
+
[RNFBSharedUtils getConfigBooleanValue:@"RNFBCrashlyticsInit"
|
|
88
|
+
key:KEY_CRASHLYTICS_IS_ERROR_GENERATION_ON_JS_CRASH_ENABLED
|
|
89
|
+
defaultValue:YES];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
+ (BOOL)isCrashlyticsJavascriptExceptionHandlerChainingEnabled {
|
|
93
|
+
return [RNFBSharedUtils
|
|
94
|
+
getConfigBooleanValue:@"RNFBCrashlyticsInit"
|
|
95
|
+
key:KEY_CRASHLYTICS_JAVASCRIPT_EXCEPTION_HANDLER_CHAINING_ENABLED
|
|
96
|
+
defaultValue:YES];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
+ (NSArray<FIRComponent *> *)componentsToRegister {
|
|
100
|
+
// Goal: enable or disable crashlytics logging based on firebase.json settings at app startup
|
|
101
|
+
//
|
|
102
|
+
// Problem: We need a correctly instantiated Crashlytics component in order to configure it
|
|
103
|
+
//
|
|
104
|
+
// Solution:
|
|
105
|
+
// 1) put the desired startup logic that requires Crashlytics dependency in deferrable block...
|
|
106
|
+
FIRComponentCreationBlock creationBlock =
|
|
107
|
+
^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) {
|
|
108
|
+
if (!container.app.isDefaultApp) {
|
|
109
|
+
return nil;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Ensure it's cached so it returns the same instance every time messaging is called.
|
|
113
|
+
*isCacheable = YES;
|
|
114
|
+
|
|
115
|
+
// 2) ... ask the SDK component system to get a correctly running dependency...
|
|
116
|
+
// Note: This is a FIRCrashlytics *, directly cast it later for practical use, reference:
|
|
117
|
+
// https://github.com/firebase/firebase-ios-sdk/blob/main/Crashlytics/Crashlytics/FIRCrashlytics.m#L282-L284
|
|
118
|
+
id<FIRCrashlyticsInstanceProvider> crashlytics =
|
|
119
|
+
FIR_COMPONENT(FIRCrashlyticsInstanceProvider, container);
|
|
120
|
+
|
|
121
|
+
// This setting is sticky. setCrashlyticsCollectionEnabled persists the setting to disk until it
|
|
122
|
+
// is explicitly set otherwise or the app is deleted. Jump to the
|
|
123
|
+
// setCrashlyticsCollectionEnabled definition to see implementation details.
|
|
124
|
+
[(FIRCrashlytics *)crashlytics
|
|
125
|
+
setCrashlyticsCollectionEnabled:self.isCrashlyticsCollectionEnabled];
|
|
126
|
+
|
|
127
|
+
// For testing: filter for this in logs to make sure this block executes via
|
|
128
|
+
// xcrun simctl spawn booted log stream --level debug --style compact |grep RNFBCrashlyticsInit
|
|
129
|
+
DLog(@"RNFBCrashlyticsInit initialization successful");
|
|
130
|
+
return nil;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// 3) ...finally: register startup block to run w/Crashlytics dependency when ready
|
|
134
|
+
FIRComponent *crashlyticsInitProvider =
|
|
135
|
+
[FIRComponent componentWithProtocol:@protocol(RNFBCrashlyticsInitProviderProtocol)
|
|
136
|
+
instantiationTiming:FIRInstantiationTimingEagerInDefaultApp
|
|
137
|
+
creationBlock:creationBlock];
|
|
138
|
+
|
|
139
|
+
return @[ crashlyticsInitProvider ];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
@end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#import <Foundation/Foundation.h>
|
|
19
|
+
|
|
20
|
+
#import <React/RCTBridgeModule.h>
|
|
21
|
+
|
|
22
|
+
@interface RNFBCrashlyticsModule : NSObject <RCTBridgeModule>
|
|
23
|
+
|
|
24
|
+
@end
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include <Foundation/Foundation.h>
|
|
19
|
+
#include <sys/sysctl.h>
|
|
20
|
+
|
|
21
|
+
#import <React/RCTConvert.h>
|
|
22
|
+
#import <React/RCTLog.h>
|
|
23
|
+
#import <React/RCTUtils.h>
|
|
24
|
+
|
|
25
|
+
#import <Firebase/Firebase.h>
|
|
26
|
+
#import "RNFBApp/RNFBSharedUtils.h"
|
|
27
|
+
#import "RNFBCrashlyticsInitProvider.h"
|
|
28
|
+
#import "RNFBCrashlyticsModule.h"
|
|
29
|
+
#import "RNFBPreferences.h"
|
|
30
|
+
|
|
31
|
+
@implementation RNFBCrashlyticsModule
|
|
32
|
+
#pragma mark -
|
|
33
|
+
#pragma mark Module Setup
|
|
34
|
+
|
|
35
|
+
RCT_EXPORT_MODULE();
|
|
36
|
+
|
|
37
|
+
- (NSDictionary *)constantsToExport {
|
|
38
|
+
NSMutableDictionary *constants = [NSMutableDictionary new];
|
|
39
|
+
constants[@"isCrashlyticsCollectionEnabled"] =
|
|
40
|
+
@([RCTConvert BOOL:@([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled])]);
|
|
41
|
+
constants[@"isErrorGenerationOnJSCrashEnabled"] =
|
|
42
|
+
@([RCTConvert BOOL:@([RNFBCrashlyticsInitProvider isErrorGenerationOnJSCrashEnabled])]);
|
|
43
|
+
constants[@"isCrashlyticsJavascriptExceptionHandlerChainingEnabled"] =
|
|
44
|
+
@([RCTConvert BOOL:@([RNFBCrashlyticsInitProvider
|
|
45
|
+
isCrashlyticsJavascriptExceptionHandlerChainingEnabled])]);
|
|
46
|
+
if ([self isDebuggerAttached]) {
|
|
47
|
+
RCTLog(
|
|
48
|
+
@"Crashlytics - WARNING: Debugger detected. Crashlytics will not receive crash reports.");
|
|
49
|
+
}
|
|
50
|
+
return constants;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
+ (BOOL)requiresMainQueueSetup {
|
|
54
|
+
return NO;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
#pragma mark -
|
|
58
|
+
#pragma mark Firebase Crashlytics Methods
|
|
59
|
+
|
|
60
|
+
RCT_EXPORT_METHOD(checkForUnsentReports
|
|
61
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
62
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
63
|
+
[[FIRCrashlytics crashlytics] checkForUnsentReportsWithCompletion:^(BOOL unsentReports) {
|
|
64
|
+
resolve([NSNumber numberWithBool:unsentReports]);
|
|
65
|
+
}];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
RCT_EXPORT_METHOD(crash) {
|
|
69
|
+
if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
|
|
70
|
+
if ([self isDebuggerAttached]) {
|
|
71
|
+
RCTLog(
|
|
72
|
+
@"Crashlytics - WARNING: Debugger detected. Crashlytics will not receive crash reports.");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// https://firebase.google.com/docs/crashlytics/test-implementation?platform=ios recommends
|
|
76
|
+
// using "@[][1]" to crash, but that gets caught by react-native and shown as a red box for
|
|
77
|
+
// debug builds. Raise SIGSEGV here to generate a hard crash.
|
|
78
|
+
int *p = 0;
|
|
79
|
+
*p = 0;
|
|
80
|
+
} else {
|
|
81
|
+
RCTLog(@"Crashlytics - INFO: crashlytics collection is not enabled, not crashing.");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
RCT_EXPORT_METHOD(crashWithStackPromise
|
|
86
|
+
: (NSDictionary *)jsErrorDict resolver
|
|
87
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
88
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
89
|
+
if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
|
|
90
|
+
if ([self isDebuggerAttached]) {
|
|
91
|
+
RCTLog(
|
|
92
|
+
@"Crashlytics - WARNING: Debugger detected. Crashlytics will not receive crash reports.");
|
|
93
|
+
}
|
|
94
|
+
[self recordJavaScriptError:jsErrorDict];
|
|
95
|
+
|
|
96
|
+
// This is strongly discouraged by Apple as "it will appear as though your app has crashed".
|
|
97
|
+
// Coincidentally, we are *in* a crash handler and have logged a crash report.
|
|
98
|
+
// It seems like the one place calling exit cleanly is valid.
|
|
99
|
+
ELog(@"Crashlytics - Crash logged. Terminating app.");
|
|
100
|
+
exit(0);
|
|
101
|
+
} else {
|
|
102
|
+
RCTLog(@"Crashlytics - INFO: crashlytics collection is not enabled, not crashing.");
|
|
103
|
+
}
|
|
104
|
+
resolve([NSNull null]);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
RCT_EXPORT_METHOD(deleteUnsentReports) { [[FIRCrashlytics crashlytics] deleteUnsentReports]; }
|
|
108
|
+
|
|
109
|
+
RCT_EXPORT_METHOD(didCrashOnPreviousExecution
|
|
110
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
111
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
112
|
+
BOOL didCrash = [[FIRCrashlytics crashlytics] didCrashDuringPreviousExecution];
|
|
113
|
+
resolve([NSNumber numberWithBool:didCrash]);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
RCT_EXPORT_METHOD(log : (NSString *)message) { [[FIRCrashlytics crashlytics] log:message]; }
|
|
117
|
+
|
|
118
|
+
RCT_EXPORT_METHOD(logPromise
|
|
119
|
+
: (NSString *)message resolver
|
|
120
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
121
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
122
|
+
[[FIRCrashlytics crashlytics] log:message];
|
|
123
|
+
resolve([NSNull null]);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
RCT_EXPORT_METHOD(sendUnsentReports) { [[FIRCrashlytics crashlytics] sendUnsentReports]; }
|
|
127
|
+
|
|
128
|
+
RCT_EXPORT_METHOD(setAttribute
|
|
129
|
+
: (NSString *)key value
|
|
130
|
+
: (NSString *)value resolver
|
|
131
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
132
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
133
|
+
if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
|
|
134
|
+
[[FIRCrashlytics crashlytics] setCustomValue:value forKey:key];
|
|
135
|
+
}
|
|
136
|
+
resolve([NSNull null]);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
RCT_EXPORT_METHOD(setAttributes
|
|
140
|
+
: (NSDictionary *)attributes resolver
|
|
141
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
142
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
143
|
+
if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
|
|
144
|
+
NSArray *keys = [attributes allKeys];
|
|
145
|
+
|
|
146
|
+
for (NSString *key in keys) {
|
|
147
|
+
[[FIRCrashlytics crashlytics] setCustomValue:attributes[key] forKey:key];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
resolve([NSNull null]);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
RCT_EXPORT_METHOD(setUserId
|
|
154
|
+
: (NSString *)userId resolver
|
|
155
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
156
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
157
|
+
if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
|
|
158
|
+
[[FIRCrashlytics crashlytics] setUserID:userId];
|
|
159
|
+
}
|
|
160
|
+
resolve([NSNull null]);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
RCT_EXPORT_METHOD(recordError : (NSDictionary *)jsErrorDict) {
|
|
164
|
+
if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
|
|
165
|
+
[self recordJavaScriptError:jsErrorDict];
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
RCT_EXPORT_METHOD(recordErrorPromise
|
|
170
|
+
: (NSDictionary *)jsErrorDict resolver
|
|
171
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
172
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
173
|
+
if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
|
|
174
|
+
[self recordJavaScriptError:jsErrorDict];
|
|
175
|
+
}
|
|
176
|
+
resolve([NSNull null]);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
RCT_EXPORT_METHOD(setCrashlyticsCollectionEnabled
|
|
180
|
+
: (BOOL)enabled resolver
|
|
181
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
182
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
183
|
+
[[RNFBPreferences shared] setBooleanValue:@"crashlytics_auto_collection_enabled"
|
|
184
|
+
boolValue:enabled];
|
|
185
|
+
resolve([NSNull null]);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
- (void)recordJavaScriptError:(NSDictionary *)jsErrorDict {
|
|
189
|
+
NSString *message = jsErrorDict[@"message"];
|
|
190
|
+
NSDictionary *stackFrames = jsErrorDict[@"frames"];
|
|
191
|
+
NSMutableArray *stackTrace = [[NSMutableArray alloc] init];
|
|
192
|
+
BOOL isUnhandledPromiseRejection = [jsErrorDict[@"isUnhandledRejection"] boolValue];
|
|
193
|
+
|
|
194
|
+
for (NSDictionary *stackFrame in stackFrames) {
|
|
195
|
+
FIRStackFrame *customFrame =
|
|
196
|
+
[FIRStackFrame stackFrameWithSymbol:stackFrame[@"fn"]
|
|
197
|
+
file:stackFrame[@"file"]
|
|
198
|
+
line:(uint32_t)[stackFrame[@"line"] intValue]];
|
|
199
|
+
[stackTrace addObject:customFrame];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
NSString *name = @"JavaScriptError";
|
|
203
|
+
if (isUnhandledPromiseRejection) {
|
|
204
|
+
name = @"UnhandledPromiseRejection";
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
FIRExceptionModel *exceptionModel = [FIRExceptionModel exceptionModelWithName:name
|
|
208
|
+
reason:message];
|
|
209
|
+
exceptionModel.stackTrace = stackTrace;
|
|
210
|
+
|
|
211
|
+
[[FIRCrashlytics crashlytics] recordExceptionModel:exceptionModel];
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Check if the debugger is attached
|
|
216
|
+
*
|
|
217
|
+
* Taken from
|
|
218
|
+
* https://github.com/plausiblelabs/plcrashreporter/blob/2dd862ce049e6f43feb355308dfc710f3af54c4d/Source/Crash%20Demo/main.m#L96
|
|
219
|
+
*
|
|
220
|
+
* @return `YES` if the debugger is attached to the current process, `NO` otherwise
|
|
221
|
+
*/
|
|
222
|
+
- (BOOL)isDebuggerAttached {
|
|
223
|
+
static BOOL debuggerIsAttached = NO;
|
|
224
|
+
|
|
225
|
+
static dispatch_once_t debuggerPredicate;
|
|
226
|
+
dispatch_once(&debuggerPredicate, ^{
|
|
227
|
+
struct kinfo_proc info;
|
|
228
|
+
size_t info_size = sizeof(info);
|
|
229
|
+
int name[4];
|
|
230
|
+
|
|
231
|
+
name[0] = CTL_KERN;
|
|
232
|
+
name[1] = KERN_PROC;
|
|
233
|
+
name[2] = KERN_PROC_PID;
|
|
234
|
+
name[3] = getpid(); // from unistd.h, included by Foundation
|
|
235
|
+
|
|
236
|
+
if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {
|
|
237
|
+
ELog(@"Crashlytics ERROR: Checking for a running debugger via sysctl() failed: %s",
|
|
238
|
+
strerror(errno));
|
|
239
|
+
debuggerIsAttached = false;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (!debuggerIsAttached && (info.kp_proc.p_flag & P_TRACED) != 0) debuggerIsAttached = true;
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
return debuggerIsAttached;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
@end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this library except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
#import <Foundation/Foundation.h>
|
|
20
|
+
|
|
21
|
+
@interface RNFBCrashlyticsNativeHelper : NSObject
|
|
22
|
+
|
|
23
|
+
+ (void)recordNativeError:(NSError *)error;
|
|
24
|
+
|
|
25
|
+
+ (void)log:(nonnull NSString *)msg;
|
|
26
|
+
|
|
27
|
+
+ (void)setCustomValue:(nullable id)value forKey:(nonnull NSString *)key;
|
|
28
|
+
|
|
29
|
+
@end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this library except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
#import "RNFBCrashlyticsNativeHelper.h"
|
|
20
|
+
#import <Firebase/Firebase.h>
|
|
21
|
+
|
|
22
|
+
@implementation RNFBCrashlyticsNativeHelper
|
|
23
|
+
|
|
24
|
+
+ (void)recordNativeError:(NSError *)error {
|
|
25
|
+
[[FIRCrashlytics crashlytics] recordError:error];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
+ (void)log:(nonnull NSString *)msg {
|
|
29
|
+
[[FIRCrashlytics crashlytics] log:msg];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
+ (void)setCustomValue:(nullable id)value forKey:(nonnull NSString *)key {
|
|
33
|
+
[[FIRCrashlytics crashlytics] setCustomValue:value forKey:key];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@end
|