@react-native-firebase/app 26.3.2 → 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 +45 -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/firebase_spm.rb +240 -95
- package/ios/RNFBApp/RNFBAppModule.mm +42 -16
- package/ios/RNFBApp/RNFBHandleMap.h +73 -0
- package/ios/RNFBApp/RNFBHandleMap.m +116 -0
- package/ios/RNFBApp/RNFBSharedUtils.m +3 -2
- package/ios/RNFBApp/RNFBUtilsModule.mm +2 -3
- 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
package/firebase_spm.rb
CHANGED
|
@@ -313,10 +313,11 @@ end
|
|
|
313
313
|
# release restructures `Pod::Installer`), it prints a `pod install`-time
|
|
314
314
|
# warning telling you to call this explicitly instead:
|
|
315
315
|
#
|
|
316
|
-
#
|
|
317
|
-
# react_native_post_install(installer, ...)
|
|
316
|
+
# post_integrate do |installer|
|
|
318
317
|
# rnfirebase_add_spm_embed_phase(installer)
|
|
319
318
|
# end
|
|
319
|
+
#
|
|
320
|
+
# Use `post_install` only if your CocoaPods version has no `post_integrate`.
|
|
320
321
|
def rnfirebase_add_spm_embed_phase(installer)
|
|
321
322
|
return unless RNFirebaseSPM.active?
|
|
322
323
|
|
|
@@ -386,7 +387,7 @@ def rnfirebase_verify_spm_embed_phase_applied!(installer)
|
|
|
386
387
|
|
|
387
388
|
Without it, this app will crash at launch with a missing-library dyld error, because Firebase's Swift Package frameworks never get copied into the app bundle.
|
|
388
389
|
|
|
389
|
-
Add `rnfirebase_add_spm_embed_phase(installer)` to your Podfile's
|
|
390
|
+
Add `rnfirebase_add_spm_embed_phase(installer)` to your Podfile's post_integrate block as a fallback, then run `pod install` again. # rubocop:disable Layout/LineLength
|
|
390
391
|
MESSAGE
|
|
391
392
|
end
|
|
392
393
|
|
|
@@ -444,6 +445,41 @@ def rnfirebase_fail_if_spm_static_linkage!(installer)
|
|
|
444
445
|
MESSAGE
|
|
445
446
|
end
|
|
446
447
|
|
|
448
|
+
# Expo's precompiled-module pre-install hook runs after Podfile pre-install
|
|
449
|
+
# hooks and changes React-Core-dependent pod targets to static libraries.
|
|
450
|
+
# That is required for Expo's own source-built pods, but RNFB's Firebase SPM
|
|
451
|
+
# products are automatic libraries: making more than one RNFB pod static
|
|
452
|
+
# absorbs the same Firebase objects into each archive and the app link fails
|
|
453
|
+
# with duplicate symbols.
|
|
454
|
+
#
|
|
455
|
+
# Restore only Expo's generated prebuilt-RNCore + dynamic-framework path, and
|
|
456
|
+
# only RNFB targets that Expo actually changed to `static_library`. Bare
|
|
457
|
+
# consumers never define `Expo::PrecompiledModules`; source-built Expo installs
|
|
458
|
+
# make `enabled?` false; static/no-framework Podfiles do not report `:dynamic`.
|
|
459
|
+
# Existing dynamic RNFB targets and explicit static frameworks are untouched.
|
|
460
|
+
def rnfirebase_restore_dynamic_linkage_after_expo_prebuilt!(installer)
|
|
461
|
+
return unless RNFirebaseSPM.active?
|
|
462
|
+
return unless defined?(Expo::PrecompiledModules)
|
|
463
|
+
return unless Expo::PrecompiledModules.respond_to?(:enabled?) &&
|
|
464
|
+
Expo::PrecompiledModules.respond_to?(:linkage)
|
|
465
|
+
return unless Expo::PrecompiledModules.enabled?
|
|
466
|
+
return unless Expo::PrecompiledModules.linkage(installer) == :dynamic
|
|
467
|
+
|
|
468
|
+
static_library = Pod::BuildType.static_library
|
|
469
|
+
dynamic_framework = Pod::BuildType.dynamic_framework
|
|
470
|
+
restored_targets = installer.pod_targets.select do |target|
|
|
471
|
+
target.name.start_with?('RNFB') && target.build_type == static_library
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
restored_targets.each do |target|
|
|
475
|
+
target.define_singleton_method(:build_type) { dynamic_framework }
|
|
476
|
+
end
|
|
477
|
+
return if restored_targets.empty? || !defined?(Pod::UI)
|
|
478
|
+
|
|
479
|
+
names = restored_targets.map(&:name).join(', ')
|
|
480
|
+
Pod::UI.puts "[react-native-firebase] Restored dynamic framework linkage after Expo prebuilt downgrade: #{names}"
|
|
481
|
+
end
|
|
482
|
+
|
|
447
483
|
# CocoaPods `TargetUUIDGenerator` replaces `@generated_uuids` with leftover
|
|
448
484
|
# `@available_uuids` before Podfile `post_install`. RN's SPM integration then
|
|
449
485
|
# calls `project.new` for Firebase package product deps; with an empty/short
|
|
@@ -527,19 +563,103 @@ end
|
|
|
527
563
|
# runs automatically on every `pod install`/`pod update`, without requiring
|
|
528
564
|
# any Podfile change from consumers.
|
|
529
565
|
#
|
|
530
|
-
#
|
|
531
|
-
#
|
|
532
|
-
#
|
|
533
|
-
#
|
|
534
|
-
# `
|
|
535
|
-
#
|
|
536
|
-
|
|
566
|
+
# User-project SPM mutations (embed phase, FirebaseCore on the app target,
|
|
567
|
+
# signature workaround, build settings). Must run *after* CocoaPods has
|
|
568
|
+
# integrated `[CP] Embed Pods Frameworks` into the app target -- see
|
|
569
|
+
# `rnfirebase_hook_cocoapods_post_install!`. Extracted so both the
|
|
570
|
+
# `post_integrate` hook (current CocoaPods) and the `post_install` fallback
|
|
571
|
+
# (older CocoaPods without `run_podfile_post_integrate_hooks`) share one body.
|
|
572
|
+
def rnfirebase_run_spm_user_project_hooks(installer)
|
|
573
|
+
begin
|
|
574
|
+
rnfirebase_add_spm_embed_phase(installer)
|
|
575
|
+
rescue StandardError => e
|
|
576
|
+
if defined?(Pod::UI)
|
|
577
|
+
Pod::UI.warn "[react-native-firebase] Couldn't embed Firebase SPM frameworks " \
|
|
578
|
+
"automatically (#{e.class}: #{e.message}). Add `rnfirebase_add_spm_embed_phase(installer)` " \
|
|
579
|
+
'to your Podfile\'s post_integrate block as a fallback.'
|
|
580
|
+
end
|
|
581
|
+
end
|
|
582
|
+
# Deliberately outside the `rescue` above: dynamic framework embedding is
|
|
583
|
+
# load-bearing (without it, the app crashes at launch with a missing-library
|
|
584
|
+
# dyld error), so if the phase still isn't on a target that needs it --
|
|
585
|
+
# whether the call raised, silently no-opped, or only partially applied --
|
|
586
|
+
# this must abort `pod install` rather than let a broken install continue.
|
|
587
|
+
rnfirebase_verify_spm_embed_phase_applied!(installer)
|
|
588
|
+
begin
|
|
589
|
+
rnfirebase_add_spm_core_to_app_target(installer)
|
|
590
|
+
rescue StandardError => e
|
|
591
|
+
if defined?(Pod::UI)
|
|
592
|
+
Pod::UI.warn "[react-native-firebase] Couldn't link FirebaseCore into the app target " \
|
|
593
|
+
"automatically (#{e.class}: #{e.message}). " \
|
|
594
|
+
'Add `rnfirebase_add_spm_core_to_app_target(installer)` ' \
|
|
595
|
+
'to your Podfile\'s post_integrate block as a fallback if your own native code calls ' \
|
|
596
|
+
'FIRApp/FIROptions APIs directly.'
|
|
597
|
+
end
|
|
598
|
+
end
|
|
599
|
+
begin
|
|
600
|
+
rnfirebase_remove_spm_core_from_app_target(installer)
|
|
601
|
+
rescue StandardError => e
|
|
602
|
+
if defined?(Pod::UI)
|
|
603
|
+
Pod::UI.warn "[react-native-firebase] Couldn't remove a stale FirebaseCore SPM link from the " \
|
|
604
|
+
"app target automatically (#{e.class}: #{e.message}). If you previously used SPM and have " \
|
|
605
|
+
'since set `$RNFirebaseDisableSPM = true`, remove the "firebase-ios-sdk" Swift Package ' \
|
|
606
|
+
'dependency from your app target manually in Xcode.'
|
|
607
|
+
end
|
|
608
|
+
end
|
|
609
|
+
begin
|
|
610
|
+
rnfirebase_fix_spm_archive_signature_collision(installer)
|
|
611
|
+
rescue StandardError => e
|
|
612
|
+
if defined?(Pod::UI)
|
|
613
|
+
Pod::UI.warn '[react-native-firebase] Couldn\'t add the Firebase/Google SPM binary ' \
|
|
614
|
+
"xcframework signature workaround automatically (#{e.class}: #{e.message}). If your " \
|
|
615
|
+
'Release archive fails with `"...xcframework-ios.signature" couldn\'t be copied to ' \
|
|
616
|
+
'"Signatures" because an item with the same name already exists`, add a Run Script ' \
|
|
617
|
+
'build phase to your app target that runs `rm -f ' \
|
|
618
|
+
'"\\${CONFIGURATION_BUILD_DIR}"/<TheNameFromTheErrorMessage>.xcframework-ios.signature`.'
|
|
619
|
+
end
|
|
620
|
+
end
|
|
621
|
+
begin
|
|
622
|
+
rnfirebase_apply_spm_build_settings(installer)
|
|
623
|
+
rescue StandardError => e
|
|
624
|
+
if defined?(Pod::UI)
|
|
625
|
+
Pod::UI.warn "[react-native-firebase] Couldn't apply Firebase SPM build settings " \
|
|
626
|
+
"automatically (#{e.class}: #{e.message}). " \
|
|
627
|
+
'Add `rnfirebase_apply_spm_build_settings(installer)` ' \
|
|
628
|
+
'to your Podfile\'s post_integrate block as a fallback if Release builds crash at launch with ' \
|
|
629
|
+
'missing FIRComponent registrations, or Xcode reports that a Firebase module such as ' \
|
|
630
|
+
'`FirebaseCoreInternal`/`FirebaseSharedSwift` cannot be resolved.'
|
|
631
|
+
end
|
|
632
|
+
end
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
# We wrap `Pod::Installer#generate_pods_project` (restore RNFB dynamic
|
|
636
|
+
# frameworks after Expo's prebuilt downgrade and CocoaPods' transitive-static
|
|
637
|
+
# validation, but before product/link-input generation),
|
|
638
|
+
# `Pod::Installer#run_podfile_post_install_hooks` (Pods project: UUID counter,
|
|
639
|
+
# RN SPM integrity, static-linkage guard) and, when present,
|
|
640
|
+
# `Pod::Installer#run_podfile_post_integrate_hooks` (user project: embed
|
|
641
|
+
# Firebase SPM frameworks + link FirebaseCore onto the app target).
|
|
642
|
+
#
|
|
643
|
+
# CocoaPods runs `post_install` *before* writing projects and *before*
|
|
644
|
+
# `integrate_user_project`. That integrator is what adds
|
|
645
|
+
# `[CP] Embed Pods Frameworks` on a clean app target and then *saves* the
|
|
646
|
+
# user `.pbxproj`. Helpers that key off that phase (or that `project.save`
|
|
647
|
+
# the app target) must therefore run in `post_integrate`, which CocoaPods
|
|
648
|
+
# calls at the end of `integrate_user_project` after that save.
|
|
649
|
+
#
|
|
650
|
+
# Expo CNG `expo prebuild --clean` always starts from a template with no CP
|
|
651
|
+
# embed phase. Running the user-project helpers from `post_install` silently
|
|
652
|
+
# skipped every native target, then integrate wrote `[CP] Embed Pods
|
|
653
|
+
# Frameworks` without `[RNFB] Embed Firebase SPM Frameworks` or a
|
|
654
|
+
# FirebaseCore `PBXBuildFile` -- undefined `_OBJC_CLASS_$_FIRApp` from
|
|
655
|
+
# AppDelegate (#9158 / CPRN-301). A committed bare-RN `ios/` folder that
|
|
656
|
+
# already had the CP phase from a prior `pod install` could look fine at
|
|
657
|
+
# `post_install` and hid this on #9164.
|
|
537
658
|
#
|
|
538
659
|
# This file is `require`d from each RNFB podspec, which CocoaPods evaluates
|
|
539
660
|
# early, during dependency resolution (itself one of the first steps inside
|
|
540
661
|
# `Installer#install!`). That's early enough for the patch installed here to
|
|
541
|
-
# affect the
|
|
542
|
-
# further down in that same `install!` run.
|
|
662
|
+
# affect the later hook calls in that same `install!` run.
|
|
543
663
|
#
|
|
544
664
|
# Why hook CocoaPods instead of React Native: `Pod::Installer` is a stable,
|
|
545
665
|
# semantically-versioned public class that the wider CocoaPods plugin
|
|
@@ -547,23 +667,27 @@ end
|
|
|
547
667
|
# changed in years. That makes it a meaningfully safer patch target than
|
|
548
668
|
# RN's private, unversioned `react-native/scripts/cocoapods/spm.rb` helper,
|
|
549
669
|
# which isn't part of any documented RN contract. If CocoaPods ever
|
|
550
|
-
# renames/removes
|
|
551
|
-
# and print a `pod install`-time warning
|
|
552
|
-
# rather than a silent runtime dyld crash) telling you to call
|
|
670
|
+
# renames/removes these methods, the guards below no-op instead of raising,
|
|
671
|
+
# and print a `pod install`-time warning telling you to call
|
|
553
672
|
# `rnfirebase_add_spm_embed_phase(installer)` from your own Podfile as a
|
|
554
|
-
# fallback.
|
|
673
|
+
# fallback. Older CocoaPods without `run_podfile_post_integrate_hooks` keeps
|
|
674
|
+
# the user-project helpers on `post_install`.
|
|
555
675
|
#
|
|
556
676
|
# `installer_class` is only ever overridden by tests -- there's no real
|
|
557
677
|
# `Pod::Installer` outside of a full CocoaPods environment.
|
|
558
678
|
def rnfirebase_hook_cocoapods_post_install!(installer_class = (Pod::Installer if defined?(Pod::Installer)))
|
|
679
|
+
generate_method = :generate_pods_project
|
|
680
|
+
generate_original_method = :rnfirebase_original_generate_pods_project
|
|
559
681
|
hook_method = :run_podfile_post_install_hooks
|
|
560
682
|
original_method = :rnfirebase_original_run_podfile_post_install_hooks
|
|
683
|
+
integrate_hook_method = :run_podfile_post_integrate_hooks
|
|
684
|
+
integrate_original_method = :rnfirebase_original_run_podfile_post_integrate_hooks
|
|
561
685
|
|
|
562
686
|
unless installer_class
|
|
563
687
|
if defined?(Pod::UI)
|
|
564
688
|
Pod::UI.warn '[react-native-firebase] `Pod::Installer` isn\'t defined -- automatic Firebase SPM setup ' \
|
|
565
689
|
'(dynamic framework embedding, etc.) was not hooked into `pod install`. Add ' \
|
|
566
|
-
'`rnfirebase_add_spm_embed_phase(installer)` to your Podfile\'s
|
|
690
|
+
'`rnfirebase_add_spm_embed_phase(installer)` to your Podfile\'s post_integrate block as a fallback.'
|
|
567
691
|
end
|
|
568
692
|
return
|
|
569
693
|
end
|
|
@@ -573,19 +697,84 @@ def rnfirebase_hook_cocoapods_post_install!(installer_class = (Pod::Installer if
|
|
|
573
697
|
if defined?(Pod::UI)
|
|
574
698
|
Pod::UI.warn "[react-native-firebase] `Pod::Installer##{hook_method}` doesn't exist (a CocoaPods " \
|
|
575
699
|
'release may have renamed or removed it) -- automatic Firebase SPM setup was not hooked into ' \
|
|
576
|
-
'`pod install`. Add `rnfirebase_add_spm_embed_phase(installer)` to your Podfile\'s
|
|
700
|
+
'`pod install`. Add `rnfirebase_add_spm_embed_phase(installer)` to your Podfile\'s post_integrate ' \
|
|
577
701
|
'block as a fallback.'
|
|
578
702
|
end
|
|
579
703
|
return
|
|
580
704
|
end
|
|
581
705
|
|
|
706
|
+
already_hooked_post_install = installer_class.method_defined?(original_method) ||
|
|
707
|
+
installer_class.private_method_defined?(original_method)
|
|
708
|
+
already_hooked_generate = installer_class.method_defined?(generate_original_method) ||
|
|
709
|
+
installer_class.private_method_defined?(generate_original_method)
|
|
710
|
+
already_hooked_post_integrate = installer_class.method_defined?(integrate_original_method) ||
|
|
711
|
+
installer_class.private_method_defined?(integrate_original_method)
|
|
712
|
+
|
|
713
|
+
generate_was_private = installer_class.private_method_defined?(generate_method)
|
|
714
|
+
generate_available = generate_was_private || installer_class.method_defined?(generate_method)
|
|
715
|
+
integrate_was_private = installer_class.private_method_defined?(integrate_hook_method)
|
|
716
|
+
post_integrate_available = integrate_was_private || installer_class.method_defined?(integrate_hook_method)
|
|
717
|
+
|
|
718
|
+
generate_unavailable_warning = :@rnfirebase_generate_pods_project_unavailable_warning
|
|
719
|
+
if !already_hooked_generate &&
|
|
720
|
+
!generate_available &&
|
|
721
|
+
defined?(Expo::PrecompiledModules) &&
|
|
722
|
+
Expo::PrecompiledModules.respond_to?(:enabled?) &&
|
|
723
|
+
Expo::PrecompiledModules.enabled? &&
|
|
724
|
+
defined?(Pod::UI) &&
|
|
725
|
+
!installer_class.instance_variable_defined?(generate_unavailable_warning)
|
|
726
|
+
Pod::UI.warn '[react-native-firebase] `Pod::Installer#generate_pods_project` does not exist ' \
|
|
727
|
+
'(a CocoaPods release may have renamed or removed it) -- Expo prebuilt RNFB ' \
|
|
728
|
+
'dynamic-linkage restoration was not hooked into `pod install`. Use the CocoaPods ' \
|
|
729
|
+
'version required by your Expo SDK and report this version combination if the app ' \
|
|
730
|
+
'links duplicate Firebase symbols.'
|
|
731
|
+
installer_class.instance_variable_set(generate_unavailable_warning, true)
|
|
732
|
+
end
|
|
733
|
+
|
|
582
734
|
# Already hooked -- e.g. a second RNFB podspec also `require`d this same
|
|
583
|
-
# file within one `pod install` process
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
735
|
+
# file within one `pod install` process. Expected and idempotent.
|
|
736
|
+
return if (already_hooked_generate || !generate_available) &&
|
|
737
|
+
already_hooked_post_install &&
|
|
738
|
+
(already_hooked_post_integrate || !post_integrate_available)
|
|
739
|
+
|
|
740
|
+
unless already_hooked_generate || !generate_available
|
|
741
|
+
installer_class.class_eval do
|
|
742
|
+
alias_method generate_original_method, generate_method
|
|
743
|
+
|
|
744
|
+
define_method(generate_method) do
|
|
745
|
+
# Expo's patched pre-install implementation has already downgraded
|
|
746
|
+
# React-Core-dependent targets, and CocoaPods has already validated
|
|
747
|
+
# that graph. Restore RNFB immediately before CocoaPods reads each
|
|
748
|
+
# pod target's build type to generate products and app link inputs.
|
|
749
|
+
begin
|
|
750
|
+
rnfirebase_restore_dynamic_linkage_after_expo_prebuilt!(self)
|
|
751
|
+
rescue StandardError => e
|
|
752
|
+
if defined?(Pod::UI)
|
|
753
|
+
Pod::UI.warn '[react-native-firebase] Expo prebuilt RNFB dynamic-linkage restoration failed ' \
|
|
754
|
+
"(#{e.class}: #{e.message}). Pod install aborted to avoid a partial restore."
|
|
755
|
+
end
|
|
756
|
+
raise
|
|
757
|
+
end
|
|
758
|
+
send(generate_original_method)
|
|
759
|
+
end
|
|
760
|
+
end
|
|
761
|
+
installer_class.send(:private, generate_method) if generate_was_private
|
|
762
|
+
end
|
|
763
|
+
|
|
764
|
+
unless already_hooked_post_integrate || !post_integrate_available
|
|
765
|
+
installer_class.class_eval do
|
|
766
|
+
alias_method integrate_original_method, integrate_hook_method
|
|
767
|
+
|
|
768
|
+
define_method(integrate_hook_method) do
|
|
769
|
+
result = send(integrate_original_method)
|
|
770
|
+
rnfirebase_run_spm_user_project_hooks(self)
|
|
771
|
+
result
|
|
772
|
+
end
|
|
773
|
+
end
|
|
774
|
+
installer_class.send(:private, integrate_hook_method) if integrate_was_private
|
|
775
|
+
end
|
|
776
|
+
|
|
777
|
+
return if already_hooked_post_install
|
|
589
778
|
|
|
590
779
|
installer_class.class_eval do
|
|
591
780
|
alias_method original_method, hook_method
|
|
@@ -599,7 +788,7 @@ def rnfirebase_hook_cocoapods_post_install!(installer_class = (Pod::Installer if
|
|
|
599
788
|
rnfirebase_fail_if_spm_static_linkage!(self)
|
|
600
789
|
# Soft ensure (warn on unexpected errors) -- paired with the hard
|
|
601
790
|
# `rnfirebase_verify_pods_project_uuid_integrity!` after original
|
|
602
|
-
# post_install
|
|
791
|
+
# post_install.
|
|
603
792
|
begin
|
|
604
793
|
rnfirebase_ensure_pods_uuid_counter_safe!(self)
|
|
605
794
|
rescue StandardError => e
|
|
@@ -614,71 +803,10 @@ def rnfirebase_hook_cocoapods_post_install!(installer_class = (Pod::Installer if
|
|
|
614
803
|
# Deliberately not rescued: if RN SPM overwrote `rootObject`, continuing
|
|
615
804
|
# would only delay the failure to Xcode with a worse diagnostic.
|
|
616
805
|
rnfirebase_verify_pods_project_uuid_integrity!(self)
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
Pod::UI.warn "[react-native-firebase] Couldn't embed Firebase SPM frameworks " \
|
|
622
|
-
"automatically (#{e.class}: #{e.message}). Add `rnfirebase_add_spm_embed_phase(installer)` " \
|
|
623
|
-
'to your Podfile\'s post_install block as a fallback.'
|
|
624
|
-
end
|
|
625
|
-
end
|
|
626
|
-
# Deliberately outside the `rescue` above, and not itself wrapped in a
|
|
627
|
-
# rescue-and-warn like the softer checks in this method: dynamic
|
|
628
|
-
# framework embedding is load-bearing (without it, the app crashes at
|
|
629
|
-
# launch with a missing-library dyld error), so if the phase still
|
|
630
|
-
# isn't actually on a target that needs it after the call above --
|
|
631
|
-
# whether that call raised, silently no-opped, or only partially
|
|
632
|
-
# applied -- this must abort `pod install` with a clear message
|
|
633
|
-
# rather than let a broken install continue, the same way
|
|
634
|
-
# `rnfirebase_fail_if_spm_static_linkage!` above is deliberately not
|
|
635
|
-
# rescued either.
|
|
636
|
-
rnfirebase_verify_spm_embed_phase_applied!(self)
|
|
637
|
-
begin
|
|
638
|
-
rnfirebase_add_spm_core_to_app_target(self)
|
|
639
|
-
rescue StandardError => e
|
|
640
|
-
if defined?(Pod::UI)
|
|
641
|
-
Pod::UI.warn "[react-native-firebase] Couldn't link FirebaseCore into the app target " \
|
|
642
|
-
"automatically (#{e.class}: #{e.message}). " \
|
|
643
|
-
'Add `rnfirebase_add_spm_core_to_app_target(installer)` ' \
|
|
644
|
-
'to your Podfile\'s post_install block as a fallback if your own native code calls ' \
|
|
645
|
-
'FIRApp/FIROptions APIs directly.'
|
|
646
|
-
end
|
|
647
|
-
end
|
|
648
|
-
begin
|
|
649
|
-
rnfirebase_remove_spm_core_from_app_target(self)
|
|
650
|
-
rescue StandardError => e
|
|
651
|
-
if defined?(Pod::UI)
|
|
652
|
-
Pod::UI.warn "[react-native-firebase] Couldn't remove a stale FirebaseCore SPM link from the " \
|
|
653
|
-
"app target automatically (#{e.class}: #{e.message}). If you previously used SPM and have " \
|
|
654
|
-
'since set `$RNFirebaseDisableSPM = true`, remove the "firebase-ios-sdk" Swift Package ' \
|
|
655
|
-
'dependency from your app target manually in Xcode.'
|
|
656
|
-
end
|
|
657
|
-
end
|
|
658
|
-
begin
|
|
659
|
-
rnfirebase_fix_spm_archive_signature_collision(self)
|
|
660
|
-
rescue StandardError => e
|
|
661
|
-
if defined?(Pod::UI)
|
|
662
|
-
Pod::UI.warn '[react-native-firebase] Couldn\'t add the Firebase/Google SPM binary ' \
|
|
663
|
-
"xcframework signature workaround automatically (#{e.class}: #{e.message}). If your " \
|
|
664
|
-
'Release archive fails with `"...xcframework-ios.signature" couldn\'t be copied to ' \
|
|
665
|
-
'"Signatures" because an item with the same name already exists`, add a Run Script ' \
|
|
666
|
-
'build phase to your app target that runs `rm -f ' \
|
|
667
|
-
'"\\${CONFIGURATION_BUILD_DIR}"/<TheNameFromTheErrorMessage>.xcframework-ios.signature`.'
|
|
668
|
-
end
|
|
669
|
-
end
|
|
670
|
-
begin
|
|
671
|
-
rnfirebase_apply_spm_build_settings(self)
|
|
672
|
-
rescue StandardError => e
|
|
673
|
-
if defined?(Pod::UI)
|
|
674
|
-
Pod::UI.warn "[react-native-firebase] Couldn't apply Firebase SPM build settings " \
|
|
675
|
-
"automatically (#{e.class}: #{e.message}). " \
|
|
676
|
-
'Add `rnfirebase_apply_spm_build_settings(installer)` ' \
|
|
677
|
-
'to your Podfile\'s post_install block as a fallback if Release builds crash at launch with ' \
|
|
678
|
-
'missing FIRComponent registrations, or Xcode reports that a Firebase module such as ' \
|
|
679
|
-
'`FirebaseCoreInternal`/`FirebaseSharedSwift` cannot be resolved.'
|
|
680
|
-
end
|
|
681
|
-
end
|
|
806
|
+
# Current CocoaPods: user-project mutations run from post_integrate
|
|
807
|
+
# (after `[CP] Embed Pods Frameworks` exists). Older CocoaPods without
|
|
808
|
+
# that hook keeps them here.
|
|
809
|
+
rnfirebase_run_spm_user_project_hooks(self) unless post_integrate_available
|
|
682
810
|
result
|
|
683
811
|
end
|
|
684
812
|
end
|
|
@@ -687,14 +815,15 @@ rescue StandardError => e
|
|
|
687
815
|
if defined?(Pod::UI)
|
|
688
816
|
Pod::UI.warn "[react-native-firebase] Couldn't hook CocoaPods to auto-embed Firebase SPM " \
|
|
689
817
|
"frameworks (#{e.class}: #{e.message}). Add `rnfirebase_add_spm_embed_phase(installer)` " \
|
|
690
|
-
'to your Podfile\'s
|
|
818
|
+
'to your Podfile\'s post_integrate block as a fallback.'
|
|
691
819
|
end
|
|
692
820
|
end
|
|
693
821
|
|
|
694
822
|
# Adds a direct SPM product dependency on `FirebaseCore` to the *app's own*
|
|
695
823
|
# native target(s) -- not just RNFB's pod targets. Runs automatically on every
|
|
696
|
-
# `pod install`/`pod update`
|
|
697
|
-
#
|
|
824
|
+
# `pod install`/`pod update` from `rnfirebase_run_spm_user_project_hooks`
|
|
825
|
+
# (post_integrate on current CocoaPods; post_install fallback otherwise) --
|
|
826
|
+
# see `rnfirebase_hook_cocoapods_post_install!` -- so you normally never
|
|
698
827
|
# need to call this yourself.
|
|
699
828
|
#
|
|
700
829
|
# Why this needs to exist: every react-native-firebase app is required to
|
|
@@ -1044,13 +1173,29 @@ def rnfirebase_apply_spm_build_settings(installer)
|
|
|
1044
1173
|
project.save if project_modified
|
|
1045
1174
|
end
|
|
1046
1175
|
|
|
1047
|
-
|
|
1176
|
+
# User-project settings are `project.save`d above. Pods settings used to
|
|
1177
|
+
# live only on the in-memory `installer.pods_project` during `post_install`,
|
|
1178
|
+
# when CocoaPods still writes that file. The user-project hooks now run
|
|
1179
|
+
# from `post_integrate` (after that write), so these mutations are lost
|
|
1180
|
+
# unless we save. Xcode 26 then keeps explicit modules on RNFB pod
|
|
1181
|
+
# targets and fails Swift compiles that import Firebase SPM internals
|
|
1182
|
+
# (`FirebaseCoreInternal`, `FirebaseSharedSwift`) with "compilation
|
|
1183
|
+
# search paths unable to resolve module dependency".
|
|
1184
|
+
pods_project = installer.pods_project
|
|
1185
|
+
return unless pods_project
|
|
1186
|
+
|
|
1187
|
+
pods_modified = false
|
|
1188
|
+
pods_project.targets.each do |target|
|
|
1048
1189
|
target.build_configurations.each do |config|
|
|
1049
1190
|
explicit_modules_settings.each do |setting|
|
|
1050
|
-
config.build_settings[setting]
|
|
1191
|
+
unless config.build_settings[setting] == 'NO'
|
|
1192
|
+
config.build_settings[setting] = 'NO'
|
|
1193
|
+
pods_modified = true
|
|
1194
|
+
end
|
|
1051
1195
|
end
|
|
1052
1196
|
end
|
|
1053
1197
|
end
|
|
1198
|
+
pods_project.save if pods_modified
|
|
1054
1199
|
end
|
|
1055
1200
|
|
|
1056
1201
|
rnfirebase_hook_cocoapods_post_install!
|
|
@@ -41,8 +41,13 @@
|
|
|
41
41
|
#endif
|
|
42
42
|
|
|
43
43
|
@interface RNFBAppModule () <NativeRNFBTurboAppSpec, RCTInvalidating>
|
|
44
|
+
|
|
45
|
+
+ (void)setCustomDomain:(nullable NSString *)authDomain forAppName:(NSString *)appName;
|
|
46
|
+
|
|
44
47
|
@end
|
|
45
48
|
|
|
49
|
+
static NSMutableDictionary<NSString *, NSString *> *customAuthDomains;
|
|
50
|
+
|
|
46
51
|
@implementation RNFBAppModule
|
|
47
52
|
|
|
48
53
|
#pragma mark -
|
|
@@ -102,11 +107,11 @@ RCT_EXPORT_MODULE(NativeRNFBTurboApp)
|
|
|
102
107
|
return constants;
|
|
103
108
|
}
|
|
104
109
|
|
|
105
|
-
- (facebook::react::ModuleConstants<JS::NativeRNFBTurboApp::Constants
|
|
110
|
+
- (facebook::react::ModuleConstants<JS::NativeRNFBTurboApp::Constants>)constantsToExport {
|
|
106
111
|
return [_RCTTypedModuleConstants newWithUnsafeDictionary:[self appConstantsDictionary]];
|
|
107
112
|
}
|
|
108
113
|
|
|
109
|
-
- (facebook::react::ModuleConstants<JS::NativeRNFBTurboApp::Constants
|
|
114
|
+
- (facebook::react::ModuleConstants<JS::NativeRNFBTurboApp::Constants>)getConstants {
|
|
110
115
|
return [self constantsToExport];
|
|
111
116
|
}
|
|
112
117
|
|
|
@@ -200,6 +205,9 @@ RCT_EXPORT_MODULE(NativeRNFBTurboApp)
|
|
|
200
205
|
RCTUnsafeExecuteOnMainQueueSync(^{
|
|
201
206
|
FIRApp *firApp;
|
|
202
207
|
NSString *appName = [appConfig valueForKey:@"name"];
|
|
208
|
+
NSString *authDomain = [options valueForKey:@"authDomain"];
|
|
209
|
+
NSString *jsAppName = (appName.length > 0) ? appName : DEFAULT_APP_DISPLAY_NAME;
|
|
210
|
+
BOOL isDefaultApp = !appName || [appName isEqualToString:DEFAULT_APP_DISPLAY_NAME];
|
|
203
211
|
|
|
204
212
|
NSString *appId = [options valueForKey:@"appId"];
|
|
205
213
|
NSString *messagingSenderId = [options valueForKey:@"messagingSenderId"];
|
|
@@ -223,17 +231,16 @@ RCT_EXPORT_MODULE(NativeRNFBTurboApp)
|
|
|
223
231
|
firOptions.appGroupID = [options valueForKey:@"appGroupId"];
|
|
224
232
|
}
|
|
225
233
|
|
|
226
|
-
if ([options valueForKey:@"authDomain"] != nil) {
|
|
227
|
-
DLog(@"RNFBAuth app: %@ customAuthDomain: %@", appName, [options valueForKey:@"authDomain"]);
|
|
228
|
-
if (customAuthDomains == nil) {
|
|
229
|
-
customAuthDomains = [[NSMutableDictionary alloc] init];
|
|
230
|
-
}
|
|
231
|
-
customAuthDomains[appName] = [options valueForKey:@"authDomain"];
|
|
232
|
-
}
|
|
233
234
|
@try {
|
|
234
|
-
if (
|
|
235
|
-
[FIRApp
|
|
236
|
-
|
|
235
|
+
if (isDefaultApp) {
|
|
236
|
+
// Native bootstrap often already called [FIRApp configure]. Still accept a JS/bridge
|
|
237
|
+
// initializeApp for the default app so customAuthDomains can be keyed by [DEFAULT].
|
|
238
|
+
if ([FIRApp defaultApp] != nil) {
|
|
239
|
+
firApp = [FIRApp defaultApp];
|
|
240
|
+
} else {
|
|
241
|
+
[FIRApp configureWithOptions:firOptions];
|
|
242
|
+
firApp = [FIRApp defaultApp];
|
|
243
|
+
}
|
|
237
244
|
} else {
|
|
238
245
|
[FIRApp configureWithName:appName options:firOptions];
|
|
239
246
|
firApp = [FIRApp appNamed:appName];
|
|
@@ -242,6 +249,9 @@ RCT_EXPORT_MODULE(NativeRNFBTurboApp)
|
|
|
242
249
|
return [RNFBSharedUtils rejectPromiseWithExceptionDict:reject exception:exception];
|
|
243
250
|
}
|
|
244
251
|
|
|
252
|
+
// Store under the JS bridge app name ([DEFAULT]), never native __FIRAPP_DEFAULT.
|
|
253
|
+
[RNFBAppModule setCustomDomain:authDomain forAppName:jsAppName];
|
|
254
|
+
|
|
245
255
|
firApp.dataCollectionDefaultEnabled =
|
|
246
256
|
(BOOL)[appConfig valueForKey:@"automaticDataCollectionEnabled"];
|
|
247
257
|
|
|
@@ -249,11 +259,25 @@ RCT_EXPORT_MODULE(NativeRNFBTurboApp)
|
|
|
249
259
|
});
|
|
250
260
|
}
|
|
251
261
|
|
|
252
|
-
static NSMutableDictionary<NSString *, NSString *> *customAuthDomains;
|
|
253
|
-
|
|
254
262
|
+ (NSString *)getCustomDomain:(NSString *)appName {
|
|
255
|
-
|
|
256
|
-
|
|
263
|
+
@synchronized(self) {
|
|
264
|
+
DLog(@"authDomains: %@", customAuthDomains);
|
|
265
|
+
return customAuthDomains[appName];
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
+ (void)setCustomDomain:(nullable NSString *)authDomain forAppName:(NSString *)appName {
|
|
270
|
+
@synchronized(self) {
|
|
271
|
+
if (authDomain != nil) {
|
|
272
|
+
DLog(@"RNFBAuth app: %@ customAuthDomain: %@", appName, authDomain);
|
|
273
|
+
if (customAuthDomains == nil) {
|
|
274
|
+
customAuthDomains = [[NSMutableDictionary alloc] init];
|
|
275
|
+
}
|
|
276
|
+
customAuthDomains[appName] = authDomain;
|
|
277
|
+
} else {
|
|
278
|
+
[customAuthDomains removeObjectForKey:appName];
|
|
279
|
+
}
|
|
280
|
+
}
|
|
257
281
|
}
|
|
258
282
|
|
|
259
283
|
- (void)setLogLevel:(NSString *)logLevel {
|
|
@@ -288,10 +312,12 @@ static NSMutableDictionary<NSString *, NSString *> *customAuthDomains;
|
|
|
288
312
|
|
|
289
313
|
[firApp deleteApp:^(BOOL success) {
|
|
290
314
|
if (success) {
|
|
315
|
+
[RNFBAppModule setCustomDomain:nil forAppName:appName];
|
|
291
316
|
resolve([NSNull null]);
|
|
292
317
|
} else {
|
|
293
318
|
[firApp deleteApp:^(BOOL success2) {
|
|
294
319
|
if (success2) {
|
|
320
|
+
[RNFBAppModule setCustomDomain:nil forAppName:appName];
|
|
295
321
|
resolve([NSNull null]);
|
|
296
322
|
} else {
|
|
297
323
|
reject(@"app/delete-app-failed", @"Failed to delete the specified app.", nil);
|
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
21
|
+
|
|
22
|
+
FOUNDATION_EXPORT NSErrorDomain const RNFBHandleMapErrorDomain;
|
|
23
|
+
|
|
24
|
+
typedef NS_ERROR_ENUM(RNFBHandleMapErrorDomain, RNFBHandleMapErrorCode){
|
|
25
|
+
RNFBHandleMapErrorCollision = 1,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Thread-safe id → handle registry. The lock only moves pointers; this class never invokes methods
|
|
30
|
+
* on stored values (no SDK cancel/remove). Callers `take` or `takeAll`, then act on the returned
|
|
31
|
+
* object(s) outside the lock. Keys are typically NSNumber or NSString.
|
|
32
|
+
*
|
|
33
|
+
* `put` is unique: an occupied id fails with `RNFBHandleMapErrorCollision`. There is no upsert.
|
|
34
|
+
* Use `putIfAbsent` (first wins), `putIfAbsentOrSame` (first wins or same instance), or
|
|
35
|
+
* `putReplacing` (last wins) for atomic upsert.
|
|
36
|
+
*
|
|
37
|
+
* Do not lock on a `RNFBHandleMap` instance. This type uses a private lock object; callers that
|
|
38
|
+
* synchronize on the map can deadlock. Never `@synchronized(handleMap)` around these methods.
|
|
39
|
+
*/
|
|
40
|
+
@interface RNFBHandleMap : NSObject
|
|
41
|
+
|
|
42
|
+
/// Registers `value` under `key`. Returns NO and sets `error` if `key` is already occupied.
|
|
43
|
+
- (BOOL)put:(id)key value:(id)value error:(NSError *_Nullable *_Nullable)error;
|
|
44
|
+
|
|
45
|
+
/// Stores `value` under `key` only when the key is free (first wins). Returns NO if occupied.
|
|
46
|
+
- (BOOL)putIfAbsent:(id)key value:(id)value;
|
|
47
|
+
|
|
48
|
+
/// Under one lock: stores when free, or YES when existing is the same instance (`==`). NO if
|
|
49
|
+
/// occupied by a different value.
|
|
50
|
+
- (BOOL)putIfAbsentOrSame:(id)key value:(id)value;
|
|
51
|
+
|
|
52
|
+
/// Atomically replaces the mapping for `key` (last wins). Returns the previous value, or nil.
|
|
53
|
+
- (nullable id)putReplacing:(id)key value:(id)value;
|
|
54
|
+
|
|
55
|
+
/// Peeks at the handle for `key` without removing it (for emit while still registered).
|
|
56
|
+
- (nullable id)get:(id)key;
|
|
57
|
+
|
|
58
|
+
/// Removes and returns the handle for `key`, or nil if absent.
|
|
59
|
+
- (nullable id)take:(id)key;
|
|
60
|
+
|
|
61
|
+
/// When `key` is mapped and `condition` returns YES for the handle, removes and returns it;
|
|
62
|
+
/// otherwise returns nil and leaves the map unchanged. Lookup, condition, and removal run under one
|
|
63
|
+
/// lock — use for check-and-take that must not race with concurrent `put` / `take` on the same key.
|
|
64
|
+
/// Keep `condition` lightweight (no SDK cancel/remove).
|
|
65
|
+
- (nullable id)takeIf:(id)key when:(BOOL (^)(id value))condition;
|
|
66
|
+
|
|
67
|
+
/// Snapshot of current values, then clear. Cancel/remove each returned object after this method
|
|
68
|
+
/// returns, not under this map's lock.
|
|
69
|
+
- (NSArray *)takeAll;
|
|
70
|
+
|
|
71
|
+
@end
|
|
72
|
+
|
|
73
|
+
NS_ASSUME_NONNULL_END
|