@react-native-firebase/app 26.3.3 → 26.4.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 +27 -0
- package/RNFBApp.podspec +1 -1
- package/android/src/main/java/io/invertase/firebase/common/RNFBHandleCollisionException.java +31 -0
- package/android/src/main/java/io/invertase/firebase/common/RNFBHandleMap.java +150 -0
- package/android/src/main/java/io/invertase/firebase/common/TaskExecutorService.java +27 -3
- package/android/src/reactnative/java/io/invertase/firebase/app/NativeRNFBTurboApp.java +3 -1
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseVersion.java +1 -1
- package/android/src/reactnative/java/io/invertase/firebase/common/RCTConvertFirebase.java +3 -2
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseJSON.java +5 -3
- package/android/src/test/java/io/invertase/firebase/app/NativeRNFBTurboAppTest.java +26 -1
- package/android/src/test/java/io/invertase/firebase/common/RNFBHandleMapTest.java +275 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitterTest.java +1 -1
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONTest.java +108 -0
- package/android/src/test/java/io/invertase/firebase/common/TaskExecutorServiceTest.java +97 -0
- package/android/src/test/java/io/invertase/firebase/utils/NativeRNFBTurboUtilsTest.java +0 -2
- package/dist/module/common/Base64.js +13 -21
- package/dist/module/common/Base64.js.map +1 -1
- package/dist/module/common/index.js +17 -9
- package/dist/module/common/index.js.map +1 -1
- package/dist/module/internal/asyncStorage.js +7 -11
- package/dist/module/internal/asyncStorage.js.map +1 -1
- package/dist/module/internal/logger.js +44 -40
- package/dist/module/internal/logger.js.map +1 -1
- package/dist/module/internal/nativeModuleAndroidIos.js +2 -29
- package/dist/module/internal/nativeModuleAndroidIos.js.map +1 -1
- package/dist/module/internal/nativeModuleDebug.js +74 -0
- package/dist/module/internal/nativeModuleDebug.js.map +1 -0
- package/dist/module/internal/nativeModuleWeb.js +9 -29
- package/dist/module/internal/nativeModuleWeb.js.map +1 -1
- package/dist/module/internal/registry/app.js +1 -1
- package/dist/module/internal/registry/app.js.map +1 -1
- package/dist/module/internal/registry/modular.js +2 -2
- package/dist/module/internal/registry/modular.js.map +1 -1
- package/dist/module/internal/registry/nativeModule.js +3 -3
- package/dist/module/internal/registry/nativeModule.js.map +1 -1
- package/dist/module/internal/web/RNFBAppModule.js +16 -15
- package/dist/module/internal/web/RNFBAppModule.js.map +1 -1
- package/dist/module/internal/web/memidb/lib/FakeEventTarget.js +3 -1
- package/dist/module/internal/web/memidb/lib/FakeEventTarget.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/lib/common/Base64.d.ts.map +1 -1
- package/dist/typescript/lib/common/index.d.ts.map +1 -1
- package/dist/typescript/lib/internal/asyncStorage.d.ts.map +1 -1
- package/dist/typescript/lib/internal/logger.d.ts.map +1 -1
- package/dist/typescript/lib/internal/nativeModuleAndroidIos.d.ts.map +1 -1
- package/dist/typescript/lib/internal/nativeModuleDebug.d.ts +2 -0
- package/dist/typescript/lib/internal/nativeModuleDebug.d.ts.map +1 -0
- package/dist/typescript/lib/internal/nativeModuleWeb.d.ts.map +1 -1
- package/dist/typescript/lib/internal/web/RNFBAppModule.d.ts +7 -7
- package/dist/typescript/lib/internal/web/RNFBAppModule.d.ts.map +1 -1
- package/dist/typescript/lib/version.d.ts +1 -1
- package/firebase-schema.json +1 -1
- package/ios/RNFBApp/RNFBAppModule.mm +40 -14
- package/ios/RNFBApp/RNFBHandleMap.h +73 -0
- package/ios/RNFBApp/RNFBHandleMap.m +116 -0
- package/ios/RNFBApp/RNFBSharedUtils.m +3 -2
- package/ios/RNFBApp/RNFBVersion.m +1 -1
- package/ios/RNFBApp.xcodeproj/project.pbxproj +6 -0
- package/ios/RNFBAppUnitTests/RNFBAppUnitTests.xcodeproj/project.pbxproj +237 -0
- package/ios/RNFBAppUnitTests/RNFBAppUnitTests.xcodeproj/xcshareddata/xcschemes/RNFBAppUnitTests.xcscheme +69 -0
- package/ios/RNFBAppUnitTests/RNFBHandleMapTests.m +238 -0
- package/lib/common/Base64.ts +10 -16
- package/lib/common/index.ts +20 -9
- package/lib/internal/asyncStorage.ts +7 -11
- package/lib/internal/logger.ts +53 -43
- package/lib/internal/nativeModuleAndroidIos.ts +2 -40
- package/lib/internal/nativeModuleDebug.ts +97 -0
- package/lib/internal/nativeModuleWeb.ts +10 -40
- package/lib/internal/registry/app.ts +1 -1
- package/lib/internal/registry/modular.ts +2 -2
- package/lib/internal/registry/nativeModule.ts +3 -3
- package/lib/internal/web/RNFBAppModule.ts +16 -15
- package/lib/internal/web/memidb/lib/FakeEventTarget.js +3 -1
- package/lib/version.ts +1 -1
- package/package.json +3 -2
- package/plugin/build/ios/appDelegate.js +18 -8
- package/plugin/src/ios/appDelegate.ts +44 -14
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
1
|
import RNFBAppModule from './web/RNFBAppModule';
|
|
3
2
|
import { APP_NATIVE_MODULE } from './constants';
|
|
3
|
+
import { createNativeModuleDebugProxy } from './nativeModuleDebug';
|
|
4
4
|
|
|
5
5
|
// Register before exporting getters — RNFBNativeEventEmitter instantiates during circular imports.
|
|
6
6
|
const nativeModuleRegistry: Record<string, Record<string, unknown>> = {
|
|
7
7
|
RNFBAppModule: RNFBAppModule as unknown as Record<string, unknown>,
|
|
8
8
|
[APP_NATIVE_MODULE]: RNFBAppModule as unknown as Record<string, unknown>,
|
|
9
9
|
};
|
|
10
|
+
const memoizedDebugProxies = new Map<string, Record<string, unknown>>();
|
|
10
11
|
|
|
11
12
|
export function getReactNativeModule(moduleName: string): Record<string, unknown> | undefined {
|
|
12
13
|
const nativeModule = nativeModuleRegistry[moduleName];
|
|
@@ -17,45 +18,13 @@ export function getReactNativeModule(moduleName: string): Record<string, unknown
|
|
|
17
18
|
if (!globalThis.RNFBDebug) {
|
|
18
19
|
return nativeModule;
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
},
|
|
28
|
-
get: (_, name) => {
|
|
29
|
-
const prop = nativeModule[name as string];
|
|
30
|
-
if (typeof prop !== 'function') return prop;
|
|
31
|
-
return (...args: unknown[]) => {
|
|
32
|
-
console.debug(
|
|
33
|
-
`[RNFB->Native][🔵] ${moduleName}.${String(name)} -> ${JSON.stringify(args)}`,
|
|
34
|
-
);
|
|
35
|
-
const result: unknown = (prop as (...args: unknown[]) => unknown)(...args);
|
|
36
|
-
if (result && typeof result === 'object' && 'then' in result) {
|
|
37
|
-
return (result as Promise<unknown>).then(
|
|
38
|
-
(res: unknown) => {
|
|
39
|
-
console.debug(
|
|
40
|
-
`[RNFB<-Native][🟢] ${moduleName}.${String(name)} <- ${JSON.stringify(res)}`,
|
|
41
|
-
);
|
|
42
|
-
return res;
|
|
43
|
-
},
|
|
44
|
-
(err: unknown) => {
|
|
45
|
-
console.debug(
|
|
46
|
-
`[RNFB<-Native][🔴] ${moduleName}.${String(name)} <- ${JSON.stringify(err)}`,
|
|
47
|
-
);
|
|
48
|
-
throw err;
|
|
49
|
-
},
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
console.debug(
|
|
53
|
-
`[RNFB<-Native][🟢] ${moduleName}.${String(name)} <- ${JSON.stringify(result)}`,
|
|
54
|
-
);
|
|
55
|
-
return result;
|
|
56
|
-
};
|
|
57
|
-
},
|
|
58
|
-
});
|
|
21
|
+
|
|
22
|
+
let debugProxy = memoizedDebugProxies.get(moduleName);
|
|
23
|
+
if (!debugProxy) {
|
|
24
|
+
debugProxy = createNativeModuleDebugProxy(moduleName, nativeModule);
|
|
25
|
+
memoizedDebugProxies.set(moduleName, debugProxy);
|
|
26
|
+
}
|
|
27
|
+
return debugProxy;
|
|
59
28
|
}
|
|
60
29
|
|
|
61
30
|
export function setReactNativeModule(
|
|
@@ -63,4 +32,5 @@ export function setReactNativeModule(
|
|
|
63
32
|
nativeModule: Record<string, unknown>,
|
|
64
33
|
): void {
|
|
65
34
|
nativeModuleRegistry[moduleName] = nativeModule;
|
|
35
|
+
memoizedDebugProxies.delete(moduleName);
|
|
66
36
|
}
|
|
@@ -27,7 +27,7 @@ type FirebaseAppConfig = ReactNativeFirebase.FirebaseAppConfig;
|
|
|
27
27
|
type FirebaseAppOptions = ReactNativeFirebase.FirebaseAppOptions;
|
|
28
28
|
type ReactNativeAsyncStorage = ReactNativeFirebase.ReactNativeAsyncStorage;
|
|
29
29
|
|
|
30
|
-
const APP_REGISTRY: Record<string, FirebaseApp> =
|
|
30
|
+
const APP_REGISTRY: Record<string, FirebaseApp> = Object.create(null);
|
|
31
31
|
let onAppCreateFn: ((app: FirebaseApp) => void) | null = null;
|
|
32
32
|
const onAppDestroyCallbacks: Array<(app: FirebaseApp) => void> = [];
|
|
33
33
|
let initializedNativeApps = false;
|
|
@@ -31,7 +31,7 @@ type ModularModuleClass<T extends FirebaseModule> = new (
|
|
|
31
31
|
) => T;
|
|
32
32
|
|
|
33
33
|
// app.name -> instanceKey -> module instance
|
|
34
|
-
const MODULAR_INSTANCES: Record<string, Record<string, FirebaseModule>> =
|
|
34
|
+
const MODULAR_INSTANCES: Record<string, Record<string, FirebaseModule>> = Object.create(null);
|
|
35
35
|
|
|
36
36
|
let destroyHookRegistered = false;
|
|
37
37
|
function ensureDestroyHook(): void {
|
|
@@ -82,7 +82,7 @@ export function getOrCreateModularInstance<T extends FirebaseModule>(
|
|
|
82
82
|
const key = customUrlOrRegion ? `${customUrlOrRegion}:${namespace}` : namespace;
|
|
83
83
|
|
|
84
84
|
if (!MODULAR_INSTANCES[_app.name]) {
|
|
85
|
-
MODULAR_INSTANCES[_app.name] =
|
|
85
|
+
MODULAR_INSTANCES[_app.name] = Object.create(null);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
if (!MODULAR_INSTANCES[_app.name]![key]) {
|
|
@@ -80,9 +80,9 @@ function createRoutingCompositeProxy(
|
|
|
80
80
|
hosts: Array<{ module: Record<string, unknown> | undefined; argToPrepend: unknown[] }>,
|
|
81
81
|
isTurboModule: boolean,
|
|
82
82
|
): WrappedNativeModule {
|
|
83
|
-
const routingMap: Record<string, RouteEntry> =
|
|
84
|
-
const memoizedMethods: Record<string, (...args: unknown[]) => unknown> =
|
|
85
|
-
const memoizedConstants: Record<string, unknown> =
|
|
83
|
+
const routingMap: Record<string, RouteEntry> = Object.create(null);
|
|
84
|
+
const memoizedMethods: Record<string, (...args: unknown[]) => unknown> = Object.create(null);
|
|
85
|
+
const memoizedConstants: Record<string, unknown> = Object.create(null);
|
|
86
86
|
|
|
87
87
|
for (const { module, argToPrepend } of hosts) {
|
|
88
88
|
if (!module) {
|
|
@@ -48,22 +48,22 @@ interface InitializeAppResult {
|
|
|
48
48
|
let jsReady = false;
|
|
49
49
|
let jsListenerCount = 0;
|
|
50
50
|
let queuedEvents: QueuedEvent[] = [];
|
|
51
|
-
let jsListeners: EventListeners =
|
|
51
|
+
let jsListeners: EventListeners = Object.create(null);
|
|
52
52
|
|
|
53
53
|
// For compatibility we have a fake preferences storage,
|
|
54
54
|
// it does not persist across app restarts.
|
|
55
|
-
let fakePreferencesStorage: PreferencesStorage =
|
|
55
|
+
let fakePreferencesStorage: PreferencesStorage = Object.create(null);
|
|
56
56
|
|
|
57
57
|
function eventsGetListenersMap(): ListenersMap {
|
|
58
58
|
return {
|
|
59
59
|
listeners: jsListenerCount,
|
|
60
60
|
queued: queuedEvents.length,
|
|
61
|
-
events: jsListeners,
|
|
61
|
+
events: Object.assign(Object.create(null), jsListeners),
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
function eventsSendEvent(eventName: string, eventBody: any): void {
|
|
66
|
-
if (!jsReady || !
|
|
66
|
+
if (!jsReady || !Object.prototype.hasOwnProperty.call(jsListeners, eventName)) {
|
|
67
67
|
const event: QueuedEvent = {
|
|
68
68
|
eventName,
|
|
69
69
|
eventBody,
|
|
@@ -174,7 +174,7 @@ export default {
|
|
|
174
174
|
*
|
|
175
175
|
* @returns The meta data
|
|
176
176
|
*/
|
|
177
|
-
metaGetAll(): Record<string, never
|
|
177
|
+
async metaGetAll(): Promise<Record<string, never>> {
|
|
178
178
|
return {};
|
|
179
179
|
},
|
|
180
180
|
|
|
@@ -184,7 +184,7 @@ export default {
|
|
|
184
184
|
*
|
|
185
185
|
* @returns The JSON data for the firebase.json file.
|
|
186
186
|
*/
|
|
187
|
-
jsonGetAll(): Record<string, never
|
|
187
|
+
async jsonGetAll(): Promise<Record<string, never>> {
|
|
188
188
|
return {};
|
|
189
189
|
},
|
|
190
190
|
|
|
@@ -206,7 +206,7 @@ export default {
|
|
|
206
206
|
* @param key - The key of the preference.
|
|
207
207
|
* @param value - The value to set.
|
|
208
208
|
*/
|
|
209
|
-
preferencesSetString(key: string, value: string): void {
|
|
209
|
+
async preferencesSetString(key: string, value: string): Promise<void> {
|
|
210
210
|
fakePreferencesStorage[key] = value;
|
|
211
211
|
},
|
|
212
212
|
|
|
@@ -216,16 +216,16 @@ export default {
|
|
|
216
216
|
*
|
|
217
217
|
* @returns The preferences.
|
|
218
218
|
*/
|
|
219
|
-
preferencesGetAll(): PreferencesStorage {
|
|
220
|
-
return Object.assign(
|
|
219
|
+
async preferencesGetAll(): Promise<PreferencesStorage> {
|
|
220
|
+
return Object.assign(Object.create(null), fakePreferencesStorage);
|
|
221
221
|
},
|
|
222
222
|
|
|
223
223
|
/**
|
|
224
224
|
* Clears all preferences.
|
|
225
225
|
* Unsupported on web.
|
|
226
226
|
*/
|
|
227
|
-
preferencesClearAll(): void {
|
|
228
|
-
fakePreferencesStorage =
|
|
227
|
+
async preferencesClearAll(): Promise<void> {
|
|
228
|
+
fakePreferencesStorage = Object.create(null);
|
|
229
229
|
},
|
|
230
230
|
|
|
231
231
|
/**
|
|
@@ -269,7 +269,7 @@ export default {
|
|
|
269
269
|
*
|
|
270
270
|
* @returns The listeners for the event.
|
|
271
271
|
*/
|
|
272
|
-
eventsGetListeners(): ListenersMap {
|
|
272
|
+
async eventsGetListeners(): Promise<ListenersMap> {
|
|
273
273
|
return eventsGetListenersMap();
|
|
274
274
|
},
|
|
275
275
|
|
|
@@ -280,8 +280,9 @@ export default {
|
|
|
280
280
|
* @param eventBody - The body of the event to send.
|
|
281
281
|
* @returns void
|
|
282
282
|
*/
|
|
283
|
-
eventsPing(eventName: string, eventBody: any):
|
|
283
|
+
async eventsPing(eventName: string, eventBody: any): Promise<any> {
|
|
284
284
|
eventsSendEvent(eventName, eventBody);
|
|
285
|
+
return eventBody;
|
|
285
286
|
},
|
|
286
287
|
|
|
287
288
|
/**
|
|
@@ -291,7 +292,7 @@ export default {
|
|
|
291
292
|
*/
|
|
292
293
|
eventsAddListener(eventName: string): void {
|
|
293
294
|
jsListenerCount++;
|
|
294
|
-
if (!
|
|
295
|
+
if (!Object.prototype.hasOwnProperty.call(jsListeners, eventName)) {
|
|
295
296
|
jsListeners[eventName] = 1;
|
|
296
297
|
} else {
|
|
297
298
|
if (jsListeners[eventName] !== undefined) {
|
|
@@ -312,7 +313,7 @@ export default {
|
|
|
312
313
|
* @param all - Optional. Whether to remove all listeners for the event.
|
|
313
314
|
*/
|
|
314
315
|
eventsRemoveListener(eventName: string, all?: boolean): void {
|
|
315
|
-
if (
|
|
316
|
+
if (Object.prototype.hasOwnProperty.call(jsListeners, eventName)) {
|
|
316
317
|
const count = jsListeners[eventName];
|
|
317
318
|
if (count !== undefined) {
|
|
318
319
|
if (count <= 1 || all) {
|
|
@@ -66,7 +66,9 @@ class FakeEventTarget {
|
|
|
66
66
|
listener.type === type && listener.callback === callback && listener.capture === capture
|
|
67
67
|
);
|
|
68
68
|
});
|
|
69
|
-
|
|
69
|
+
if (i >= 0) {
|
|
70
|
+
this.listeners.splice(i, 1);
|
|
71
|
+
}
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
// http://www.w3.org/TR/dom/#dispatching-events
|
package/lib/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '26.
|
|
2
|
+
export const version = '26.4.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-native-firebase/app",
|
|
3
|
-
"version": "26.
|
|
3
|
+
"version": "26.4.0",
|
|
4
4
|
"author": "Invertase <oss@invertase.io> (http://invertase.io)",
|
|
5
5
|
"description": "A well tested, feature rich Firebase implementation for React Native, supporting iOS & Android. Individual module support for Admob, Analytics, Auth, Crash Reporting, Cloud Firestore, Database, Dynamic Links, Functions, Messaging (FCM), Remote Config, Storage and more.",
|
|
6
6
|
"main": "./dist/module/index.js",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"compile": "bob build",
|
|
33
33
|
"prepare": "npm run build && npm run build:plugin && npm run compile"
|
|
34
34
|
},
|
|
35
|
+
"homepage": "https://rnfirebase.io",
|
|
35
36
|
"repository": {
|
|
36
37
|
"type": "git",
|
|
37
38
|
"url": "https://github.com/invertase/react-native-firebase",
|
|
@@ -184,5 +185,5 @@
|
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
187
|
},
|
|
187
|
-
"gitHead": "
|
|
188
|
+
"gitHead": "06701af5fdc19bae9f379567eadb29dfe81953c0"
|
|
188
189
|
}
|
|
@@ -10,6 +10,22 @@ exports.modifyAppDelegateAsync = modifyAppDelegateAsync;
|
|
|
10
10
|
const config_plugins_1 = require("@expo/config-plugins");
|
|
11
11
|
const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
|
|
12
12
|
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
function addImport(contents, importLine, existingImportMatcher, preferredAnchorMatcher, anyImportMatcher) {
|
|
14
|
+
if (existingImportMatcher.test(contents)) {
|
|
15
|
+
return contents;
|
|
16
|
+
}
|
|
17
|
+
const newline = contents.includes('\r\n') ? '\r\n' : '\n';
|
|
18
|
+
const preferredAnchor = preferredAnchorMatcher.exec(contents);
|
|
19
|
+
if (preferredAnchor?.index !== undefined) {
|
|
20
|
+
const insertionPoint = preferredAnchor.index + preferredAnchor[0].length;
|
|
21
|
+
return `${contents.slice(0, insertionPoint)}${newline}${importLine}${contents.slice(insertionPoint)}`;
|
|
22
|
+
}
|
|
23
|
+
const firstImport = anyImportMatcher.exec(contents);
|
|
24
|
+
if (firstImport?.index !== undefined) {
|
|
25
|
+
return `${contents.slice(0, firstImport.index)}${importLine}${newline}${contents.slice(firstImport.index)}`;
|
|
26
|
+
}
|
|
27
|
+
return `${importLine}${newline}${contents}`;
|
|
28
|
+
}
|
|
13
29
|
function modifyObjcAppDelegate(contents) {
|
|
14
30
|
const methodInvocationBlock = `[FIRApp configure];`;
|
|
15
31
|
// https://regex101.com/r/mPgaq6/1
|
|
@@ -18,10 +34,7 @@ function modifyObjcAppDelegate(contents) {
|
|
|
18
34
|
// if the above regex fails, we can use this one as a fallback:
|
|
19
35
|
const fallbackInvocationLineMatcher = /-\s*\(BOOL\)\s*application:\s*\(UIApplication\s*\*\s*\)\s*\w+\s+didFinishLaunchingWithOptions:/g;
|
|
20
36
|
// Add import
|
|
21
|
-
|
|
22
|
-
contents = contents.replace(/#import "AppDelegate.h"/g, `#import "AppDelegate.h"
|
|
23
|
-
#import <Firebase/Firebase.h>`);
|
|
24
|
-
}
|
|
37
|
+
contents = addImport(contents, '#import <Firebase/Firebase.h>', /^[ \t]*#import\s+<Firebase\/Firebase\.h>[ \t]*$/m, /^[ \t]*#import\s+"AppDelegate\.h"[ \t]*$/m, /^[ \t]*#import\b[^\r\n]*$/m);
|
|
25
38
|
// To avoid potential issues with existing changes from older plugin versions
|
|
26
39
|
if (contents.includes(methodInvocationBlock)) {
|
|
27
40
|
return contents;
|
|
@@ -63,10 +76,7 @@ function modifySwiftAppDelegate(contents) {
|
|
|
63
76
|
const methodInvocationBlock = `FirebaseApp.configure()`;
|
|
64
77
|
const methodInvocationLineMatcher = /(?:self\.moduleName\s*=\s*"([^"]*)")|(?:factory\.startReactNative\()/;
|
|
65
78
|
// Add import
|
|
66
|
-
|
|
67
|
-
contents = contents.replace(/import Expo/g, `import Expo
|
|
68
|
-
import FirebaseCore`);
|
|
69
|
-
}
|
|
79
|
+
contents = addImport(contents, 'import FirebaseCore', /^[ \t]*import\s+FirebaseCore[ \t]*$/m, /^[ \t]*import\s+Expo[ \t]*$/m, /^[ \t]*import\b[^\r\n]*$/m);
|
|
70
80
|
// To avoid potential issues with existing changes from older plugin versions
|
|
71
81
|
if (contents.includes(methodInvocationBlock)) {
|
|
72
82
|
return contents;
|
|
@@ -3,6 +3,36 @@ import { AppDelegateProjectFile } from '@expo/config-plugins/build/ios/Paths';
|
|
|
3
3
|
import { mergeContents } from '@expo/config-plugins/build/utils/generateCode';
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
|
|
6
|
+
function addImport(
|
|
7
|
+
contents: string,
|
|
8
|
+
importLine: string,
|
|
9
|
+
existingImportMatcher: RegExp,
|
|
10
|
+
preferredAnchorMatcher: RegExp,
|
|
11
|
+
anyImportMatcher: RegExp,
|
|
12
|
+
): string {
|
|
13
|
+
if (existingImportMatcher.test(contents)) {
|
|
14
|
+
return contents;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const newline = contents.includes('\r\n') ? '\r\n' : '\n';
|
|
18
|
+
const preferredAnchor = preferredAnchorMatcher.exec(contents);
|
|
19
|
+
if (preferredAnchor?.index !== undefined) {
|
|
20
|
+
const insertionPoint = preferredAnchor.index + preferredAnchor[0].length;
|
|
21
|
+
return `${contents.slice(0, insertionPoint)}${newline}${importLine}${contents.slice(
|
|
22
|
+
insertionPoint,
|
|
23
|
+
)}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const firstImport = anyImportMatcher.exec(contents);
|
|
27
|
+
if (firstImport?.index !== undefined) {
|
|
28
|
+
return `${contents.slice(0, firstImport.index)}${importLine}${newline}${contents.slice(
|
|
29
|
+
firstImport.index,
|
|
30
|
+
)}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return `${importLine}${newline}${contents}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
6
36
|
export function modifyObjcAppDelegate(contents: string): string {
|
|
7
37
|
const methodInvocationBlock = `[FIRApp configure];`;
|
|
8
38
|
// https://regex101.com/r/mPgaq6/1
|
|
@@ -15,13 +45,13 @@ export function modifyObjcAppDelegate(contents: string): string {
|
|
|
15
45
|
/-\s*\(BOOL\)\s*application:\s*\(UIApplication\s*\*\s*\)\s*\w+\s+didFinishLaunchingWithOptions:/g;
|
|
16
46
|
|
|
17
47
|
// Add import
|
|
18
|
-
|
|
19
|
-
contents
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
48
|
+
contents = addImport(
|
|
49
|
+
contents,
|
|
50
|
+
'#import <Firebase/Firebase.h>',
|
|
51
|
+
/^[ \t]*#import\s+<Firebase\/Firebase\.h>[ \t]*$/m,
|
|
52
|
+
/^[ \t]*#import\s+"AppDelegate\.h"[ \t]*$/m,
|
|
53
|
+
/^[ \t]*#import\b[^\r\n]*$/m,
|
|
54
|
+
);
|
|
25
55
|
|
|
26
56
|
// To avoid potential issues with existing changes from older plugin versions
|
|
27
57
|
if (contents.includes(methodInvocationBlock)) {
|
|
@@ -74,13 +104,13 @@ export function modifySwiftAppDelegate(contents: string): string {
|
|
|
74
104
|
/(?:self\.moduleName\s*=\s*"([^"]*)")|(?:factory\.startReactNative\()/;
|
|
75
105
|
|
|
76
106
|
// Add import
|
|
77
|
-
|
|
78
|
-
contents
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
import
|
|
82
|
-
|
|
83
|
-
|
|
107
|
+
contents = addImport(
|
|
108
|
+
contents,
|
|
109
|
+
'import FirebaseCore',
|
|
110
|
+
/^[ \t]*import\s+FirebaseCore[ \t]*$/m,
|
|
111
|
+
/^[ \t]*import\s+Expo[ \t]*$/m,
|
|
112
|
+
/^[ \t]*import\b[^\r\n]*$/m,
|
|
113
|
+
);
|
|
84
114
|
|
|
85
115
|
// To avoid potential issues with existing changes from older plugin versions
|
|
86
116
|
if (contents.includes(methodInvocationBlock)) {
|