@react-native-firebase/crashlytics 27.0.0 → 27.1.0
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 +8 -0
- package/android/build.gradle +1 -0
- package/android/proguard-rules.pro +20 -0
- package/android/src/main/java/io/invertase/firebase/crashlytics/NativeRNFBTurboCrashlytics.java +11 -4
- package/android/src/main/java/io/invertase/firebase/crashlytics/ReactNativeFirebaseCrashlyticsFatalExit.java +117 -0
- package/android/src/main/java/io/invertase/firebase/crashlytics/ReactNativeFirebaseCrashlyticsInternal.java +80 -0
- package/android/src/test/java/io/invertase/firebase/crashlytics/ReactNativeFirebaseCrashlyticsFatalExitBarrierTest.java +122 -0
- package/android/src/test/java/io/invertase/firebase/crashlytics/ReactNativeFirebaseCrashlyticsFatalExitTest.java +189 -0
- package/android/src/test/java/io/invertase/firebase/crashlytics/ReactNativeFirebaseCrashlyticsInternalTest.java +199 -0
- package/dist/module/version.js +1 -1
- package/dist/typescript/lib/index.d.ts +1 -1
- package/dist/typescript/lib/version.d.ts +1 -1
- package/ios/RNFBCrashlytics/RNFBCrashlyticsHelper.h +40 -0
- package/ios/RNFBCrashlytics/RNFBCrashlyticsHelper.m +73 -0
- package/ios/RNFBCrashlytics/RNFBCrashlyticsModule.mm +21 -7
- package/ios/RNFBCrashlyticsUnitTests/HostStubs/Firebase/FIRCrashlyticsHostStub.m +66 -0
- package/ios/RNFBCrashlyticsUnitTests/HostStubs/Firebase/Firebase.h +9 -0
- package/ios/RNFBCrashlyticsUnitTests/RNFBCrashlyticsFatalExitTests.m +268 -0
- package/ios/RNFBCrashlyticsUnitTests/RNFBCrashlyticsUnitTests.xcodeproj/project.pbxproj +4 -0
- package/ios_config.sh +14 -4
- package/lib/version.ts +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,268 @@
|
|
|
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
|
+
#import <XCTest/XCTest.h>
|
|
18
|
+
|
|
19
|
+
#import <Firebase/Firebase.h>
|
|
20
|
+
#import "RNFBCrashlyticsHelper.h"
|
|
21
|
+
|
|
22
|
+
@interface RNFBCrashlyticsFatalExitTests : XCTestCase
|
|
23
|
+
@end
|
|
24
|
+
|
|
25
|
+
@implementation RNFBCrashlyticsFatalExitTests {
|
|
26
|
+
NSMutableArray<NSString *> *_events;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
- (void)setUp {
|
|
30
|
+
[super setUp];
|
|
31
|
+
[FIRCrashlytics resetTestState];
|
|
32
|
+
_events = [NSMutableArray new];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
- (void)tearDown {
|
|
36
|
+
[FIRCrashlytics resetTestState];
|
|
37
|
+
[super tearDown];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
- (void)appendEvent:(NSString *)event {
|
|
41
|
+
@synchronized(_events) {
|
|
42
|
+
[_events addObject:event];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
- (NSArray<NSString *> *)eventsSnapshot {
|
|
47
|
+
@synchronized(_events) {
|
|
48
|
+
return [_events copy];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
- (void)recordFatal {
|
|
53
|
+
[RNFBCrashlyticsHelper recordJavaScriptErrorWithMessage:@"fatal"
|
|
54
|
+
frames:@[]
|
|
55
|
+
isUnhandledPromiseRejection:NO];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Lets late watchdog / queue blocks run so "at most once" assertions are meaningful. */
|
|
59
|
+
- (void)drainFor:(NSTimeInterval)seconds {
|
|
60
|
+
XCTestExpectation *drained = [self expectationWithDescription:@"drained"];
|
|
61
|
+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(seconds * NSEC_PER_SEC)),
|
|
62
|
+
dispatch_get_main_queue(), ^{
|
|
63
|
+
[drained fulfill];
|
|
64
|
+
});
|
|
65
|
+
[self waitForExpectations:@[ drained ] timeout:seconds + 5];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Returns once every block already enqueued on serial `queue` has run (a happens-before edge). */
|
|
69
|
+
- (void)drainQueue:(dispatch_queue_t)queue {
|
|
70
|
+
dispatch_block_t noop = ^{
|
|
71
|
+
};
|
|
72
|
+
dispatch_sync(queue, noop);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
- (void)testShared_isProductionSingleton {
|
|
76
|
+
XCTAssertNotNil([RNFBCrashlyticsFatalExit shared]);
|
|
77
|
+
XCTAssertEqual([RNFBCrashlyticsFatalExit shared], [RNFBCrashlyticsFatalExit shared]);
|
|
78
|
+
XCTAssertEqualWithAccuracy(RNFBCrashlyticsFatalExitWatchdogTimeout, 2.0, 0.0001);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
- (void)testRecordThenTerminate_savesOnMainBeforeTerminatorRuns {
|
|
82
|
+
FIRCrashlytics.onExceptionModelSaved = ^(FIRExceptionModel *model) {
|
|
83
|
+
[self appendEvent:[@"save:" stringByAppendingString:model.reason]];
|
|
84
|
+
};
|
|
85
|
+
XCTestExpectation *terminated = [self expectationWithDescription:@"terminated"];
|
|
86
|
+
__block NSUInteger terminations = 0;
|
|
87
|
+
// Held suspended until the main-queue terminate has run, so the watchdog cannot win under load.
|
|
88
|
+
dispatch_queue_t watchdogQueue =
|
|
89
|
+
dispatch_queue_create("rnfb.crashlytics.test.watchdog", DISPATCH_QUEUE_SERIAL);
|
|
90
|
+
dispatch_suspend(watchdogQueue);
|
|
91
|
+
RNFBCrashlyticsFatalExit *fatalExit = [[RNFBCrashlyticsFatalExit alloc]
|
|
92
|
+
initWithTerminator:^{
|
|
93
|
+
terminations += 1;
|
|
94
|
+
[self appendEvent:@"exit"];
|
|
95
|
+
XCTAssertTrue([NSThread isMainThread]);
|
|
96
|
+
[terminated fulfill];
|
|
97
|
+
}
|
|
98
|
+
terminateQueue:dispatch_get_main_queue()
|
|
99
|
+
watchdogQueue:watchdogQueue
|
|
100
|
+
watchdogTimeout:0.2];
|
|
101
|
+
|
|
102
|
+
// Production calls in on the module's own (non-main) method queue.
|
|
103
|
+
__block BOOL started = NO;
|
|
104
|
+
dispatch_queue_t moduleQueue =
|
|
105
|
+
dispatch_queue_create("rnfb.crashlytics.test.module", DISPATCH_QUEUE_SERIAL);
|
|
106
|
+
dispatch_async(moduleQueue, ^{
|
|
107
|
+
started = [fatalExit recordThenTerminate:^{
|
|
108
|
+
[self recordFatal];
|
|
109
|
+
}];
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
[self waitForExpectations:@[ terminated ] timeout:5];
|
|
113
|
+
dispatch_resume(watchdogQueue);
|
|
114
|
+
[self drainFor:0.4]; // past the watchdog, which must not terminate again
|
|
115
|
+
[self drainQueue:watchdogQueue];
|
|
116
|
+
[self drainQueue:moduleQueue]; // `started` is written on moduleQueue
|
|
117
|
+
|
|
118
|
+
XCTAssertTrue(started);
|
|
119
|
+
XCTAssertEqual(terminations, 1u);
|
|
120
|
+
NSArray *expected = @[ @"save:fatal", @"exit" ];
|
|
121
|
+
XCTAssertEqualObjects([self eventsSnapshot], expected);
|
|
122
|
+
XCTAssertEqual(FIRCrashlytics.savedExceptionModels.count, 1u);
|
|
123
|
+
XCTAssertEqualObjects(FIRCrashlytics.savedExceptionModels.firstObject.name, @"JavaScriptError");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
- (void)testRecordThenTerminate_contextInitPending_terminatesBeforeSave {
|
|
127
|
+
[FIRCrashlytics holdContextInit];
|
|
128
|
+
FIRCrashlytics.onExceptionModelSaved = ^(FIRExceptionModel *model) {
|
|
129
|
+
[self appendEvent:[@"save:" stringByAppendingString:model.reason]];
|
|
130
|
+
};
|
|
131
|
+
XCTestExpectation *terminated = [self expectationWithDescription:@"terminated"];
|
|
132
|
+
__block NSUInteger terminations = 0;
|
|
133
|
+
__block NSUInteger savedAtExit = NSUIntegerMax;
|
|
134
|
+
__block BOOL recordedAtExit = NO;
|
|
135
|
+
dispatch_queue_t watchdogQueue =
|
|
136
|
+
dispatch_queue_create("rnfb.crashlytics.test.watchdog", DISPATCH_QUEUE_SERIAL);
|
|
137
|
+
dispatch_suspend(watchdogQueue);
|
|
138
|
+
RNFBCrashlyticsFatalExit *fatalExit = [[RNFBCrashlyticsFatalExit alloc]
|
|
139
|
+
initWithTerminator:^{
|
|
140
|
+
terminations += 1;
|
|
141
|
+
savedAtExit = FIRCrashlytics.savedExceptionModels.count;
|
|
142
|
+
recordedAtExit = FIRCrashlytics.lastRecordedExceptionModel != nil;
|
|
143
|
+
[self appendEvent:@"exit"];
|
|
144
|
+
[FIRCrashlytics fulfillContextInit];
|
|
145
|
+
[terminated fulfill];
|
|
146
|
+
}
|
|
147
|
+
terminateQueue:dispatch_get_main_queue()
|
|
148
|
+
watchdogQueue:watchdogQueue
|
|
149
|
+
watchdogTimeout:0.2];
|
|
150
|
+
|
|
151
|
+
__block BOOL started = NO;
|
|
152
|
+
dispatch_queue_t moduleQueue =
|
|
153
|
+
dispatch_queue_create("rnfb.crashlytics.test.module", DISPATCH_QUEUE_SERIAL);
|
|
154
|
+
dispatch_async(moduleQueue, ^{
|
|
155
|
+
started = [fatalExit recordThenTerminate:^{
|
|
156
|
+
[self recordFatal];
|
|
157
|
+
}];
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
[self waitForExpectations:@[ terminated ] timeout:5];
|
|
161
|
+
dispatch_resume(watchdogQueue);
|
|
162
|
+
[self drainFor:0.4];
|
|
163
|
+
[self drainQueue:watchdogQueue];
|
|
164
|
+
[self drainQueue:moduleQueue];
|
|
165
|
+
|
|
166
|
+
XCTAssertTrue(started);
|
|
167
|
+
XCTAssertEqual(terminations, 1u);
|
|
168
|
+
XCTAssertTrue(recordedAtExit);
|
|
169
|
+
XCTAssertEqual(savedAtExit, 0u);
|
|
170
|
+
NSArray *expected = @[ @"exit", @"save:fatal" ];
|
|
171
|
+
XCTAssertEqualObjects([self eventsSnapshot], expected);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
- (void)testWatchdog_terminatesWhenTerminateQueueIsHung {
|
|
175
|
+
dispatch_queue_t hungQueue = dispatch_queue_create("rnfb.crashlytics.test.hung", 0);
|
|
176
|
+
dispatch_semaphore_t release = dispatch_semaphore_create(0);
|
|
177
|
+
dispatch_async(hungQueue, ^{
|
|
178
|
+
dispatch_semaphore_wait(release, DISPATCH_TIME_FOREVER);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
XCTestExpectation *terminated = [self expectationWithDescription:@"terminated"];
|
|
182
|
+
__block NSUInteger terminations = 0;
|
|
183
|
+
__block BOOL terminatedWhileHung = NO;
|
|
184
|
+
__block BOOL hung = YES;
|
|
185
|
+
RNFBCrashlyticsFatalExit *fatalExit = [[RNFBCrashlyticsFatalExit alloc]
|
|
186
|
+
initWithTerminator:^{
|
|
187
|
+
terminations += 1;
|
|
188
|
+
terminatedWhileHung = hung;
|
|
189
|
+
[terminated fulfill];
|
|
190
|
+
}
|
|
191
|
+
terminateQueue:hungQueue
|
|
192
|
+
watchdogQueue:dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)
|
|
193
|
+
watchdogTimeout:0.1];
|
|
194
|
+
|
|
195
|
+
XCTAssertTrue([fatalExit recordThenTerminate:^{
|
|
196
|
+
[self recordFatal];
|
|
197
|
+
}]);
|
|
198
|
+
[self waitForExpectations:@[ terminated ] timeout:5];
|
|
199
|
+
|
|
200
|
+
hung = NO;
|
|
201
|
+
dispatch_semaphore_signal(release);
|
|
202
|
+
[self drainQueue:hungQueue]; // the queued terminate block has now run
|
|
203
|
+
|
|
204
|
+
XCTAssertTrue(terminatedWhileHung);
|
|
205
|
+
XCTAssertEqual(terminations, 1u);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
- (void)testRecordRaises_stillTerminatesAndIgnoresLaterFatals {
|
|
209
|
+
XCTestExpectation *terminated = [self expectationWithDescription:@"terminated"];
|
|
210
|
+
__block NSUInteger terminations = 0;
|
|
211
|
+
RNFBCrashlyticsFatalExit *fatalExit = [[RNFBCrashlyticsFatalExit alloc]
|
|
212
|
+
initWithTerminator:^{
|
|
213
|
+
terminations += 1;
|
|
214
|
+
[terminated fulfill];
|
|
215
|
+
}
|
|
216
|
+
terminateQueue:dispatch_get_main_queue()
|
|
217
|
+
watchdogQueue:dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)
|
|
218
|
+
watchdogTimeout:0.1];
|
|
219
|
+
|
|
220
|
+
BOOL first = [fatalExit recordThenTerminate:^{
|
|
221
|
+
[NSException raise:NSInternalInconsistencyException format:@"record failed"];
|
|
222
|
+
}];
|
|
223
|
+
BOOL second = [fatalExit recordThenTerminate:^{
|
|
224
|
+
[self recordFatal];
|
|
225
|
+
}];
|
|
226
|
+
|
|
227
|
+
[self waitForExpectations:@[ terminated ] timeout:5];
|
|
228
|
+
[self drainFor:0.3];
|
|
229
|
+
|
|
230
|
+
XCTAssertTrue(first);
|
|
231
|
+
XCTAssertFalse(second);
|
|
232
|
+
XCTAssertEqual(terminations, 1u);
|
|
233
|
+
XCTAssertEqual(FIRCrashlytics.savedExceptionModels.count, 0u);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
- (void)testSecondFatalWhileTerminating_isIgnored {
|
|
237
|
+
XCTestExpectation *terminated = [self expectationWithDescription:@"terminated"];
|
|
238
|
+
__block NSUInteger terminations = 0;
|
|
239
|
+
__block NSUInteger records = 0;
|
|
240
|
+
RNFBCrashlyticsFatalExit *fatalExit = [[RNFBCrashlyticsFatalExit alloc]
|
|
241
|
+
initWithTerminator:^{
|
|
242
|
+
terminations += 1;
|
|
243
|
+
[terminated fulfill];
|
|
244
|
+
}
|
|
245
|
+
terminateQueue:dispatch_get_main_queue()
|
|
246
|
+
watchdogQueue:dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)
|
|
247
|
+
watchdogTimeout:0.1];
|
|
248
|
+
|
|
249
|
+
BOOL first = [fatalExit recordThenTerminate:^{
|
|
250
|
+
records += 1;
|
|
251
|
+
[self recordFatal];
|
|
252
|
+
}];
|
|
253
|
+
BOOL second = [fatalExit recordThenTerminate:^{
|
|
254
|
+
records += 1;
|
|
255
|
+
[self recordFatal];
|
|
256
|
+
}];
|
|
257
|
+
|
|
258
|
+
[self waitForExpectations:@[ terminated ] timeout:5];
|
|
259
|
+
[self drainFor:0.3];
|
|
260
|
+
|
|
261
|
+
XCTAssertTrue(first);
|
|
262
|
+
XCTAssertFalse(second);
|
|
263
|
+
XCTAssertEqual(records, 1u);
|
|
264
|
+
XCTAssertEqual(terminations, 1u);
|
|
265
|
+
XCTAssertEqual(FIRCrashlytics.savedExceptionModels.count, 1u);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
@end
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
CL1000000000000000000020 /* RNFBCrashlyticsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = CL1000000000000000000021 /* RNFBCrashlyticsHelper.m */; };
|
|
14
14
|
CL1000000000000000000022 /* RNFBCrashlyticsHelperHostStubTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CL1000000000000000000023 /* RNFBCrashlyticsHelperHostStubTests.m */; };
|
|
15
15
|
CL1000000000000000000024 /* FIRCrashlyticsHostStub.m in Sources */ = {isa = PBXBuildFile; fileRef = CL1000000000000000000025 /* FIRCrashlyticsHostStub.m */; };
|
|
16
|
+
CL1000000000000000000027 /* RNFBCrashlyticsFatalExitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CL1000000000000000000028 /* RNFBCrashlyticsFatalExitTests.m */; };
|
|
16
17
|
/* End PBXBuildFile section */
|
|
17
18
|
|
|
18
19
|
/* Begin PBXFileReference section */
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
CL1000000000000000000021 /* RNFBCrashlyticsHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNFBCrashlyticsHelper.m; path = ../RNFBCrashlytics/RNFBCrashlyticsHelper.m; sourceTree = SOURCE_ROOT; };
|
|
24
25
|
CL1000000000000000000023 /* RNFBCrashlyticsHelperHostStubTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNFBCrashlyticsHelperHostStubTests.m; sourceTree = "<group>"; };
|
|
25
26
|
CL1000000000000000000025 /* FIRCrashlyticsHostStub.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FIRCrashlyticsHostStub.m; path = HostStubs/Firebase/FIRCrashlyticsHostStub.m; sourceTree = "<group>"; };
|
|
27
|
+
CL1000000000000000000028 /* RNFBCrashlyticsFatalExitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNFBCrashlyticsFatalExitTests.m; sourceTree = "<group>"; };
|
|
26
28
|
CL1000000000000000000026 /* RNFBCrashlyticsHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNFBCrashlyticsHelper.h; path = ../RNFBCrashlytics/RNFBCrashlyticsHelper.h; sourceTree = SOURCE_ROOT; };
|
|
27
29
|
/* End PBXFileReference section */
|
|
28
30
|
|
|
@@ -62,6 +64,7 @@
|
|
|
62
64
|
CL1000000000000000000026 /* RNFBCrashlyticsHelper.h */,
|
|
63
65
|
CL1000000000000000000021 /* RNFBCrashlyticsHelper.m */,
|
|
64
66
|
CL1000000000000000000023 /* RNFBCrashlyticsHelperHostStubTests.m */,
|
|
67
|
+
CL1000000000000000000028 /* RNFBCrashlyticsFatalExitTests.m */,
|
|
65
68
|
CL1000000000000000000025 /* FIRCrashlyticsHostStub.m */,
|
|
66
69
|
);
|
|
67
70
|
name = Sources;
|
|
@@ -129,6 +132,7 @@
|
|
|
129
132
|
CL1000000000000000000020 /* RNFBCrashlyticsHelper.m in Sources */,
|
|
130
133
|
CL1000000000000000000024 /* FIRCrashlyticsHostStub.m in Sources */,
|
|
131
134
|
CL1000000000000000000022 /* RNFBCrashlyticsHelperHostStubTests.m in Sources */,
|
|
135
|
+
CL1000000000000000000027 /* RNFBCrashlyticsFatalExitTests.m in Sources */,
|
|
132
136
|
);
|
|
133
137
|
runOnlyForDeploymentPostprocessing = 0;
|
|
134
138
|
};
|
package/ios_config.sh
CHANGED
|
@@ -16,6 +16,16 @@
|
|
|
16
16
|
#
|
|
17
17
|
set -e
|
|
18
18
|
|
|
19
|
+
# upload-symbols talks to the network and has no timeout of its own, so a stalled
|
|
20
|
+
# request can hang the whole build. perl's alarm is used because macOS has no
|
|
21
|
+
# `timeout`. A timeout exits non-zero, which the callers below report as a
|
|
22
|
+
# warning without failing the build.
|
|
23
|
+
UPLOAD_SYMBOLS_TIMEOUT_SEC="${RNFB_CRASHLYTICS_UPLOAD_TIMEOUT_SEC:-300}"
|
|
24
|
+
|
|
25
|
+
run_upload_symbols() {
|
|
26
|
+
perl -e 'alarm shift; exec @ARGV' "${UPLOAD_SYMBOLS_TIMEOUT_SEC}" "$@"
|
|
27
|
+
}
|
|
28
|
+
|
|
19
29
|
if [[ ${PODS_ROOT} && -f "${PODS_ROOT}/FirebaseCrashlytics/run" ]]; then
|
|
20
30
|
echo "info: Exec FirebaseCrashlytics Run from Pods"
|
|
21
31
|
if ! "${PODS_ROOT}/FirebaseCrashlytics/run"; then
|
|
@@ -49,14 +59,14 @@ else
|
|
|
49
59
|
echo "warning: GoogleService-Info.plist not found at ${PROJECT_DIR}/${TARGET_NAME}/GoogleService-Info.plist or ${PROJECT_DIR}/GoogleService-Info.plist. Skipping dSYM upload."
|
|
50
60
|
elif [[ -x "${SPM_UPLOAD_SYMBOLS}" ]]; then
|
|
51
61
|
echo "info: Exec FirebaseCrashlytics upload-symbols from SPM"
|
|
52
|
-
if ! "${SPM_UPLOAD_SYMBOLS}" -gsp "${GSP_PATH}" -p ios "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}"; then
|
|
53
|
-
echo "warning: FirebaseCrashlytics upload-symbols (SPM) failed; continuing without failing the build. Common causes: no network, invalid/placeholder GoogleService-Info.plist credentials, or Firebase project mismatch."
|
|
62
|
+
if ! run_upload_symbols "${SPM_UPLOAD_SYMBOLS}" -gsp "${GSP_PATH}" -p ios "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}"; then
|
|
63
|
+
echo "warning: FirebaseCrashlytics upload-symbols (SPM) failed or timed out; continuing without failing the build. Common causes: no network, invalid/placeholder GoogleService-Info.plist credentials, or Firebase project mismatch."
|
|
54
64
|
fi
|
|
55
65
|
elif [[ -f "${SPM_UPLOAD_SYMBOLS}" ]]; then
|
|
56
66
|
echo "info: Exec FirebaseCrashlytics upload-symbols from SPM (chmod +x)"
|
|
57
67
|
chmod +x "${SPM_UPLOAD_SYMBOLS}"
|
|
58
|
-
if ! "${SPM_UPLOAD_SYMBOLS}" -gsp "${GSP_PATH}" -p ios "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}"; then
|
|
59
|
-
echo "warning: FirebaseCrashlytics upload-symbols (SPM) failed; continuing without failing the build. Common causes: no network, invalid/placeholder GoogleService-Info.plist credentials, or Firebase project mismatch."
|
|
68
|
+
if ! run_upload_symbols "${SPM_UPLOAD_SYMBOLS}" -gsp "${GSP_PATH}" -p ios "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}"; then
|
|
69
|
+
echo "warning: FirebaseCrashlytics upload-symbols (SPM) failed or timed out; continuing without failing the build. Common causes: no network, invalid/placeholder GoogleService-Info.plist credentials, or Firebase project mismatch."
|
|
60
70
|
fi
|
|
61
71
|
else
|
|
62
72
|
echo "warning: FirebaseCrashlytics run script not found at CocoaPods, framework, or SPM paths. Skipping dSYM upload."
|
package/lib/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '27.
|
|
2
|
+
export const version = '27.1.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-native-firebase/crashlytics",
|
|
3
|
-
"version": "27.
|
|
3
|
+
"version": "27.1.0",
|
|
4
4
|
"author": "Invertase <oss@invertase.io> (http://invertase.io)",
|
|
5
5
|
"description": "React Native Firebase - Firebase Crashlytics is a lightweight, realtime crash reporter that helps you track, prioritize, and fix stability issues that erode your app quality. React Native Firebase provides automatic crash reporting for both native and JavaScript errors, including unhandled promise rejections.",
|
|
6
6
|
"main": "./dist/module/index.js",
|
|
@@ -49,14 +49,14 @@
|
|
|
49
49
|
"crashlytics"
|
|
50
50
|
],
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@react-native-firebase/app": "27.
|
|
52
|
+
"@react-native-firebase/app": "27.1.0",
|
|
53
53
|
"expo": ">=47.0.0"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"stacktrace-js": "^2.0.2"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@react-native-firebase/app": "27.
|
|
59
|
+
"@react-native-firebase/app": "27.1.0",
|
|
60
60
|
"expo": "^55.0.18",
|
|
61
61
|
"react-native-builder-bob": "^0.41.0",
|
|
62
62
|
"typescript": "^6.0.3"
|
|
@@ -104,5 +104,5 @@
|
|
|
104
104
|
]
|
|
105
105
|
]
|
|
106
106
|
},
|
|
107
|
-
"gitHead": "
|
|
107
|
+
"gitHead": "c65e1ee3b78bcd0c5b66996100d7d1e579ca1614"
|
|
108
108
|
}
|