diff --git a/.github/workflows/crashlytics.yml b/.github/workflows/crashlytics.yml index 5638d5d35bc..f24d0f63de5 100644 --- a/.github/workflows/crashlytics.yml +++ b/.github/workflows/crashlytics.yml @@ -25,20 +25,23 @@ jobs: strategy: matrix: target: [ios, tvos, macos, watchos --skip-tests] - os: [macos-14] flags: [ '--use-modular-headers --skip-tests', '' ] - xcode: [Xcode_15.2, Xcode_16] - runs-on: ${{ matrix.os }} + build-env: + - os: macos-14 + xcode: Xcode_15.2 + - os: macos-15 + xcode: Xcode_16.1 + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: scripts/setup_bundler.sh - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - uses: nick-fields/retry@v3 with: timeout_minutes: 120 @@ -85,22 +88,22 @@ jobs: xcode: Xcode_15.4 target: iOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: iOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: tvOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: macOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: watchOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: catalyst - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: visionOS runs-on: ${{ matrix.os }} steps: @@ -149,7 +152,7 @@ jobs: env: plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} - runs-on: macos-14 + runs-on: macos-15 steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 diff --git a/.github/workflows/dynamiclinks.yml b/.github/workflows/dynamiclinks.yml index 61439d6cc3c..9304532dc90 100644 --- a/.github/workflows/dynamiclinks.yml +++ b/.github/workflows/dynamiclinks.yml @@ -114,7 +114,7 @@ jobs: env: plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} - runs-on: macos-14 + runs-on: macos-15 steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 diff --git a/.github/workflows/inappmessaging.yml b/.github/workflows/inappmessaging.yml index c8d70fbeff4..9464fa3a245 100644 --- a/.github/workflows/inappmessaging.yml +++ b/.github/workflows/inappmessaging.yml @@ -24,14 +24,17 @@ jobs: strategy: matrix: podspec: [FirebaseInAppMessaging.podspec] - os: [macos-14] - xcode: [Xcode_15.2, Xcode_16] - runs-on: ${{ matrix.os }} + build-env: + - os: macos-14 + xcode: Xcode_15.2 + - os: macos-15 + xcode: Xcode_16.1 + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - name: Setup Bundler run: scripts/setup_bundler.sh - name: FirebaseInAppMessaging @@ -97,7 +100,7 @@ jobs: - os: macos-14 xcode: Xcode_15.4 - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -139,7 +142,7 @@ jobs: env: plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} - runs-on: macos-14 + runs-on: macos-15 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/installations.yml b/.github/workflows/installations.yml index 3a1da8aa802..d0913c2ed19 100644 --- a/.github/workflows/installations.yml +++ b/.github/workflows/installations.yml @@ -25,15 +25,14 @@ jobs: matrix: # TODO: macos tests are blocked by https://github.com/erikdoe/ocmock/pull/532 target: [ios, tvos, macos --skip-tests, watchos] - os: [macos-14] - include: + build-env: - os: macos-14 - xcode: Xcode_15.3 + xcode: Xcode_15.2 test-specs: unit,integration - - os: macos-14 - xcode: Xcode_16 + - os: macos-15 + xcode: Xcode_16.1 test-specs: unit - runs-on: ${{ matrix.os }} + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 @@ -50,12 +49,12 @@ jobs: id: secrets run: echo "::set-output name=val::$([[ -z $plist_secret ]] && echo "0" || echo "1")" - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - name: Build and test run: | export FIS_INTEGRATION_TESTS_REQUIRED=${{ steps.secrets.outputs.val }} scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseInstallations.podspec \ - --platforms=${{ matrix.target }} --test-specs=${{ matrix.test-specs }} + --platforms=${{ matrix.target }} --test-specs=${{ matrix.build-env.test-specs }} spm-package-resolved: env: @@ -93,22 +92,22 @@ jobs: xcode: Xcode_15.4 target: iOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: iOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: tvOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: macOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: watchOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: catalyst - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: visionOS runs-on: ${{ matrix.os }} steps: diff --git a/.github/workflows/remoteconfig.yml b/.github/workflows/remoteconfig.yml index eb5cae871c7..2036d8ab274 100644 --- a/.github/workflows/remoteconfig.yml +++ b/.github/workflows/remoteconfig.yml @@ -62,28 +62,27 @@ jobs: # TODO: macos tests are blocked by https://github.com/erikdoe/ocmock/pull/532 target: [ios, tvos, macos --skip-tests, watchos] podspec: [FirebaseRemoteConfig.podspec] - os: [macos-14] - include: + build-env: - os: macos-14 xcode: Xcode_15.3 # TODO(#13078): Fix testing infra to enforce warnings again. tests: --allow-warnings # Flaky tests on CI - - os: macos-14 - xcode: Xcode_16 + - os: macos-15 + xcode: Xcode_16.1 tests: --skip-tests - runs-on: ${{ matrix.os }} + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: scripts/setup_bundler.sh - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - name: Build and test run: | scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb ${{ matrix.podspec }} --platforms=${{ matrix.target }} \ - ${{ matrix.tests }} + ${{ matrix.build-env.tests }} spm-package-resolved: env: @@ -124,27 +123,27 @@ jobs: target: iOS test: spm - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: iOS test: spm - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: tvOS test: spm - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: macOS test: spm - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: watchOS test: spmbuildonly - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: catalyst test: spm - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: visionOS test: spm runs-on: ${{ matrix.os }} @@ -184,7 +183,7 @@ jobs: env: plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} - runs-on: macos-14 + runs-on: macos-15 steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 diff --git a/.github/workflows/sessions.yml b/.github/workflows/sessions.yml index 73fff13c7aa..cddd363aebe 100644 --- a/.github/workflows/sessions.yml +++ b/.github/workflows/sessions.yml @@ -24,30 +24,29 @@ jobs: strategy: matrix: target: [ios, tvos, macos, watchos] - os: [macos-14] - include: + build-env: - os: macos-14 xcode: Xcode_15.3 tests: # Flaky tests on CI - - os: macos-14 - xcode: Xcode_16 + - os: macos-15 + xcode: Xcode_16.1 tests: --skip-tests - runs-on: ${{ matrix.os }} + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: scripts/setup_bundler.sh - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - uses: nick-fields/retry@v3 with: timeout_minutes: 120 max_attempts: 3 retry_on: error retry_wait_seconds: 120 - command: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseSessions.podspec --platforms=${{ matrix.target }} ${{ matrix.tests }} + command: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseSessions.podspec --platforms=${{ matrix.target }} ${{ matrix.build-env.tests }} spm-package-resolved: env: @@ -86,22 +85,22 @@ jobs: xcode: Xcode_15.4 target: iOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: iOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: tvOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: macOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: watchOS - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: catalyst - os: macos-15 - xcode: Xcode_16 + xcode: Xcode_16.1 target: visionOS runs-on: ${{ matrix.os }} steps: diff --git a/.github/workflows/storage.yml b/.github/workflows/storage.yml index 220f98b5741..790e8ebd39d 100644 --- a/.github/workflows/storage.yml +++ b/.github/workflows/storage.yml @@ -139,8 +139,8 @@ jobs: #- os: macos-13 # xcode: Xcode_14.2 # TODO: the legacy ObjC quickstart doesn't build with Xcode 15. - swift: swift - os: macos-14 - xcode: Xcode_15.3 + os: macos-15 + xcode: Xcode_16.1 env: plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} diff --git a/.github/workflows/zip.yml b/.github/workflows/zip.yml index 2dd23dcc7fd..2db3f9d86be 100644 --- a/.github/workflows/zip.yml +++ b/.github/workflows/zip.yml @@ -30,7 +30,7 @@ jobs: package-release: # Don't run on private repo. if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' - runs-on: macos-13 + runs-on: macos-14 steps: - uses: actions/checkout@v4 - uses: mikehardy/buildcache-action@c87cea0ccd718971d6cc39e672c4f26815b6c126 @@ -58,7 +58,7 @@ jobs: build: # Don't run on private repo unless it is a PR. if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' - runs-on: macos-13 + runs-on: macos-14 steps: - uses: actions/checkout@v4 - name: Xcode 15.2 @@ -75,7 +75,7 @@ jobs: strategy: matrix: linking_type: [static, dynamic] - runs-on: macos-13 + runs-on: macos-14 steps: - uses: actions/checkout@v4 - uses: mikehardy/buildcache-action@c87cea0ccd718971d6cc39e672c4f26815b6c126 @@ -111,14 +111,13 @@ jobs: SDK: "ABTesting" strategy: matrix: - os: [macos-13, macos-14] artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] - include: - - os: macos-13 - xcode: Xcode_15.2 + build-env: - os: macos-14 - xcode: Xcode_16 - runs-on: ${{ matrix.os }} + xcode: Xcode_15.2 + - os: macos-15 + xcode: Xcode_16.1 + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - name: Get framework dir @@ -134,7 +133,7 @@ jobs: find "${GITHUB_WORKSPACE}" -name "Firebase*latest.zip" -exec unzip -d "${HOME}"/ios_frameworks/ {} + - uses: actions/checkout@v4 - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - name: Setup quickstart env: LEGACY: true @@ -173,11 +172,11 @@ jobs: SDK: "Authentication" strategy: matrix: - os: [macos-14] + os: [macos-15] artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] include: - - os: macos-14 - xcode: Xcode_16 + - os: macos-15 + xcode: Xcode_16.1 runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -225,14 +224,13 @@ jobs: SDK: "Config" strategy: matrix: - os: [macos-13, macos-14] artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] - include: - - os: macos-13 - xcode: Xcode_15.2 + build-env: - os: macos-14 - xcode: Xcode_16 - runs-on: ${{ matrix.os }} + xcode: Xcode_15.2 + - os: macos-15 + xcode: Xcode_16.1 + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - name: Get framework dir @@ -247,7 +245,7 @@ jobs: mkdir -p "${HOME}"/ios_frameworks/ find "${GITHUB_WORKSPACE}" -name "Firebase*latest.zip" -exec unzip -d "${HOME}"/ios_frameworks/ {} + - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - name: Setup Swift Quickstart run: SAMPLE="$SDK" TARGET="${SDK}Example" scripts/setup_quickstart_framework.sh \ @@ -277,14 +275,13 @@ jobs: SDK: "Crashlytics" strategy: matrix: - os: [macos-13, macos-14] artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] - include: - - os: macos-13 - xcode: Xcode_15.2 + build-env: - os: macos-14 - xcode: Xcode_16 - runs-on: ${{ matrix.os }} + xcode: Xcode_15.2 + - os: macos-15 + xcode: Xcode_16.1 + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - name: Get framework dir @@ -300,7 +297,7 @@ jobs: find "${GITHUB_WORKSPACE}" -name "Firebase*latest.zip" -exec unzip -d "${HOME}"/ios_frameworks/ {} + - uses: actions/checkout@v4 - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - name: Setup quickstart env: LEGACY: true @@ -352,7 +349,7 @@ jobs: SDK: "Database" strategy: matrix: - os: [macos-13] + os: [macos-14] xcode: [Xcode_15.2] artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] runs-on: ${{ matrix.os }} @@ -404,14 +401,13 @@ jobs: SDK: "DynamicLinks" strategy: matrix: - os: [macos-13, macos-14] artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] - include: - - os: macos-13 - xcode: Xcode_15.2 + build-env: - os: macos-14 - xcode: Xcode_16 - runs-on: ${{ matrix.os }} + xcode: Xcode_15.2 + - os: macos-15 + xcode: Xcode_16.1 + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - name: Get framework dir @@ -430,7 +426,7 @@ jobs: "${HOME}"/ios_frameworks/Firebase/FirebaseDynamicLinks/* \ "${HOME}"/ios_frameworks/Firebase/FirebaseAnalytics/* - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - name: Setup Swift Quickstart run: SAMPLE="$SDK" TARGET="${SDK}ExampleSwift" scripts/setup_quickstart_framework.sh - name: Update Environment Variable For DynamicLinks @@ -464,14 +460,13 @@ jobs: SDK: "Firestore" strategy: matrix: - os: [macos-13, macos-14] artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] - include: - - os: macos-13 - xcode: Xcode_15.2 + build-env: - os: macos-14 - xcode: Xcode_16 - runs-on: ${{ matrix.os }} + xcode: Xcode_15.2 + - os: macos-15 + xcode: Xcode_16.1 + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - name: Get framework dir @@ -493,7 +488,7 @@ jobs: "${HOME}"/ios_frameworks/Firebase/FirebaseAuth/* \ "${HOME}"/ios_frameworks/Firebase/FirebaseAnalytics/* - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - name: Install Secret GoogleService-Info.plist run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/qs-firestore.plist.gpg \ quickstart-ios/firestore/GoogleService-Info.plist "$plist_secret" @@ -505,7 +500,7 @@ jobs: - uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: quickstart_artifacts_firestore_${{ matrix.artifact }}_${{ matrix.os }} + name: quickstart_artifacts_firestore_${{ matrix.artifact }}_${{ matrix.build-env.os }} path: quickstart_artifacts_firestore.zip check_framework_firestore_symbols: @@ -514,7 +509,7 @@ jobs: needs: package-head env: FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1 - runs-on: macos-13 + runs-on: macos-14 steps: - name: Xcode 15.2 run: sudo xcode-select -s /Applications/Xcode_15.2.app/Contents/Developer @@ -549,14 +544,13 @@ jobs: SDK: "InAppMessaging" strategy: matrix: - os: [macos-13, macos-14] artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] - include: - - os: macos-13 - xcode: Xcode_15.2 + build-env: - os: macos-14 - xcode: Xcode_16 - runs-on: ${{ matrix.os }} + xcode: Xcode_15.2 + - os: macos-15 + xcode: Xcode_16.1 + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - name: Get framework dir @@ -577,7 +571,7 @@ jobs: "${HOME}"/ios_frameworks/Firebase/FirebaseInAppMessaging/* \ "${HOME}"/ios_frameworks/Firebase/FirebaseAnalytics/* - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - name: Setup swift quickstart run: SAMPLE="$SDK" TARGET="${SDK}ExampleSwift" scripts/setup_quickstart_framework.sh - name: Install Secret GoogleService-Info.plist @@ -606,14 +600,13 @@ jobs: SDK: "Messaging" strategy: matrix: - os: [macos-13, macos-14] artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] - include: - - os: macos-13 - xcode: Xcode_15.2 + build-env: - os: macos-14 - xcode: Xcode_16 - runs-on: ${{ matrix.os }} + xcode: Xcode_15.2 + - os: macos-15 + xcode: Xcode_16.1 + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - name: Get framework dir @@ -633,7 +626,7 @@ jobs: "${HOME}"/ios_frameworks/Firebase/FirebaseMessaging/* \ "${HOME}"/ios_frameworks/Firebase/FirebaseAnalytics/* - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - name: Setup swift quickstart run: SAMPLE="$SDK" TARGET="${SDK}ExampleSwift" scripts/setup_quickstart_framework.sh - name: Install Secret GoogleService-Info.plist @@ -662,14 +655,13 @@ jobs: SDK: "Storage" strategy: matrix: - os: [macos-13, macos-14] artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] - include: - - os: macos-13 - xcode: Xcode_15.2 + build-env: - os: macos-14 - xcode: Xcode_16 - runs-on: ${{ matrix.os }} + xcode: Xcode_15.2 + - os: macos-15 + xcode: Xcode_16.1 + runs-on: ${{ matrix.build-env.os }} steps: - uses: actions/checkout@v4 - name: Get framework dir @@ -692,7 +684,7 @@ jobs: "${HOME}"/ios_frameworks/Firebase/FirebaseAuth/* \ "${HOME}"/ios_frameworks/Firebase/FirebaseAnalytics/* - name: Xcode - run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer - name: Setup swift quickstart env: LEGACY: true diff --git a/Firebase.podspec b/Firebase.podspec index 50b992a43d1..c014f07db07 100644 --- a/Firebase.podspec +++ b/Firebase.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Firebase' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase' s.description = <<-DESC @@ -36,14 +36,14 @@ Simplify your app development, grow your user base, and monetize more effectivel ss.ios.deployment_target = '12.0' ss.osx.deployment_target = '10.15' ss.tvos.deployment_target = '13.0' - ss.ios.dependency 'FirebaseAnalytics', '~> 11.5.0' - ss.osx.dependency 'FirebaseAnalytics', '~> 11.5.0' - ss.tvos.dependency 'FirebaseAnalytics', '~> 11.5.0' + ss.ios.dependency 'FirebaseAnalytics', '~> 11.6.0' + ss.osx.dependency 'FirebaseAnalytics', '~> 11.6.0' + ss.tvos.dependency 'FirebaseAnalytics', '~> 11.6.0' ss.dependency 'Firebase/CoreOnly' end s.subspec 'CoreOnly' do |ss| - ss.dependency 'FirebaseCore', '11.5.0' + ss.dependency 'FirebaseCore', '~> 11.6.0' ss.source_files = 'CoreOnly/Sources/Firebase.h' ss.preserve_paths = 'CoreOnly/Sources/module.modulemap' if ENV['FIREBASE_POD_REPO_FOR_DEV_POD'] then @@ -79,13 +79,13 @@ Simplify your app development, grow your user base, and monetize more effectivel ss.ios.deployment_target = '12.0' ss.osx.deployment_target = '10.15' ss.tvos.deployment_target = '13.0' - ss.dependency 'FirebaseAnalytics/WithoutAdIdSupport', '~> 11.5.0' + ss.dependency 'FirebaseAnalytics/WithoutAdIdSupport', '~> 11.6.0' ss.dependency 'Firebase/CoreOnly' end s.subspec 'ABTesting' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseABTesting', '~> 11.5.0' + ss.dependency 'FirebaseABTesting', '~> 11.6.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '13.0' ss.osx.deployment_target = '10.15' @@ -95,13 +95,13 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'AppDistribution' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.ios.dependency 'FirebaseAppDistribution', '~> 11.5.0-beta' + ss.ios.dependency 'FirebaseAppDistribution', '~> 11.6.0-beta' ss.ios.deployment_target = '13.0' end s.subspec 'AppCheck' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseAppCheck', '~> 11.5.0' + ss.dependency 'FirebaseAppCheck', '~> 11.6.0' ss.ios.deployment_target = '13.0' ss.osx.deployment_target = '10.15' ss.tvos.deployment_target = '13.0' @@ -110,7 +110,7 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'Auth' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseAuth', '~> 11.5.0' + ss.dependency 'FirebaseAuth', '~> 11.6.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '13.0' ss.osx.deployment_target = '10.15' @@ -120,7 +120,7 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'Crashlytics' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseCrashlytics', '~> 11.5.0' + ss.dependency 'FirebaseCrashlytics', '~> 11.6.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '12.0' ss.osx.deployment_target = '10.15' @@ -130,7 +130,7 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'Database' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseDatabase', '~> 11.5.0' + ss.dependency 'FirebaseDatabase', '~> 11.6.0' # Standard platforms PLUS watchOS 7. ss.ios.deployment_target = '13.0' ss.osx.deployment_target = '10.15' @@ -140,13 +140,13 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'DynamicLinks' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.ios.dependency 'FirebaseDynamicLinks', '~> 11.5.0' + ss.ios.dependency 'FirebaseDynamicLinks', '~> 11.6.0' ss.ios.deployment_target = '13.0' end s.subspec 'Firestore' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseFirestore', '~> 11.5.0' + ss.dependency 'FirebaseFirestore', '~> 11.6.0' ss.ios.deployment_target = '13.0' ss.osx.deployment_target = '10.15' ss.tvos.deployment_target = '13.0' @@ -154,7 +154,7 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'Functions' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseFunctions', '~> 11.5.0' + ss.dependency 'FirebaseFunctions', '~> 11.6.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '13.0' ss.osx.deployment_target = '10.15' @@ -164,20 +164,20 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'InAppMessaging' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.ios.dependency 'FirebaseInAppMessaging', '~> 11.5.0-beta' - ss.tvos.dependency 'FirebaseInAppMessaging', '~> 11.5.0-beta' + ss.ios.dependency 'FirebaseInAppMessaging', '~> 11.6.0-beta' + ss.tvos.dependency 'FirebaseInAppMessaging', '~> 11.6.0-beta' ss.ios.deployment_target = '13.0' ss.tvos.deployment_target = '13.0' end s.subspec 'Installations' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseInstallations', '~> 11.5.0' + ss.dependency 'FirebaseInstallations', '~> 11.6.0' end s.subspec 'Messaging' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseMessaging', '~> 11.5.0' + ss.dependency 'FirebaseMessaging', '~> 11.6.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '13.0' ss.osx.deployment_target = '10.15' @@ -187,7 +187,7 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'MLModelDownloader' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseMLModelDownloader', '~> 11.5.0-beta' + ss.dependency 'FirebaseMLModelDownloader', '~> 11.6.0-beta' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '13.0' ss.osx.deployment_target = '10.15' @@ -197,15 +197,15 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'Performance' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.ios.dependency 'FirebasePerformance', '~> 11.5.0' - ss.tvos.dependency 'FirebasePerformance', '~> 11.5.0' + ss.ios.dependency 'FirebasePerformance', '~> 11.6.0' + ss.tvos.dependency 'FirebasePerformance', '~> 11.6.0' ss.ios.deployment_target = '13.0' ss.tvos.deployment_target = '13.0' end s.subspec 'RemoteConfig' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseRemoteConfig', '~> 11.5.0' + ss.dependency 'FirebaseRemoteConfig', '~> 11.6.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '13.0' ss.osx.deployment_target = '10.15' @@ -215,7 +215,7 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'Storage' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseStorage', '~> 11.5.0' + ss.dependency 'FirebaseStorage', '~> 11.6.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '13.0' ss.osx.deployment_target = '10.15' diff --git a/FirebaseABTesting.podspec b/FirebaseABTesting.podspec index d988bbac272..76a3c6eacc6 100644 --- a/FirebaseABTesting.podspec +++ b/FirebaseABTesting.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseABTesting' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase ABTesting' s.description = <<-DESC @@ -52,7 +52,7 @@ Firebase Cloud Messaging and Firebase Remote Config in your app. 'GCC_C_LANGUAGE_STANDARD' => 'c99', 'HEADER_SEARCH_PATHS' => '"${PODS_TARGET_SRCROOT}"' } - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.test_spec 'unit' do |unit_tests| unit_tests.scheme = { :code_coverage => true } diff --git a/FirebaseAnalytics.podspec b/FirebaseAnalytics.podspec index 125dd7e6f01..9e109930a87 100644 --- a/FirebaseAnalytics.podspec +++ b/FirebaseAnalytics.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAnalytics' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase Analytics for iOS' s.description = <<-DESC @@ -26,7 +26,7 @@ Pod::Spec.new do |s| s.libraries = 'c++', 'sqlite3', 'z' s.frameworks = 'StoreKit' - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.dependency 'FirebaseInstallations', '~> 11.0' s.dependency 'GoogleUtilities/AppDelegateSwizzler', '~> 8.0' s.dependency 'GoogleUtilities/MethodSwizzler', '~> 8.0' @@ -37,12 +37,12 @@ Pod::Spec.new do |s| s.default_subspecs = 'AdIdSupport' s.subspec 'AdIdSupport' do |ss| - ss.dependency 'GoogleAppMeasurement', '11.5.0' + ss.dependency 'GoogleAppMeasurement', '11.6.0' ss.vendored_frameworks = 'Frameworks/FirebaseAnalytics.xcframework' end s.subspec 'WithoutAdIdSupport' do |ss| - ss.dependency 'GoogleAppMeasurement/WithoutAdIdSupport', '11.5.0' + ss.dependency 'GoogleAppMeasurement/WithoutAdIdSupport', '11.6.0' ss.vendored_frameworks = 'Frameworks/FirebaseAnalytics.xcframework' end diff --git a/FirebaseAnalyticsOnDeviceConversion.podspec b/FirebaseAnalyticsOnDeviceConversion.podspec index e03608aa555..4d57ab96f1b 100644 --- a/FirebaseAnalyticsOnDeviceConversion.podspec +++ b/FirebaseAnalyticsOnDeviceConversion.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAnalyticsOnDeviceConversion' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'On device conversion measurement plugin for FirebaseAnalytics. Not intended for direct use.' s.description = <<-DESC @@ -18,7 +18,7 @@ Pod::Spec.new do |s| s.cocoapods_version = '>= 1.12.0' - s.dependency 'GoogleAppMeasurementOnDeviceConversion', '11.5.0' + s.dependency 'GoogleAppMeasurementOnDeviceConversion', '11.6.0' s.static_framework = true diff --git a/FirebaseAppCheck.podspec b/FirebaseAppCheck.podspec index a80ebd8451a..7f8995ac47c 100644 --- a/FirebaseAppCheck.podspec +++ b/FirebaseAppCheck.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAppCheck' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase App Check SDK.' s.description = <<-DESC @@ -46,7 +46,7 @@ Pod::Spec.new do |s| s.dependency 'AppCheckCore', '~> 11.0' s.dependency 'FirebaseAppCheckInterop', '~> 11.0' - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.dependency 'GoogleUtilities/Environment', '~> 8.0' s.dependency 'GoogleUtilities/UserDefaults', '~> 8.0' diff --git a/FirebaseAppCheckInterop.podspec b/FirebaseAppCheckInterop.podspec index 0496fe9832b..fe888c5a945 100644 --- a/FirebaseAppCheckInterop.podspec +++ b/FirebaseAppCheckInterop.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAppCheckInterop' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Interfaces that allow other Firebase SDKs to use AppCheck functionality.' s.description = <<-DESC diff --git a/FirebaseAppDistribution.podspec b/FirebaseAppDistribution.podspec index c5230bda665..647a88b941c 100644 --- a/FirebaseAppDistribution.podspec +++ b/FirebaseAppDistribution.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAppDistribution' - s.version = '11.5.0-beta' + s.version = '11.6.0-beta' s.summary = 'App Distribution for Firebase iOS SDK.' s.description = <<-DESC @@ -30,7 +30,7 @@ iOS SDK for App Distribution for Firebase. ] s.public_header_files = base_dir + 'Public/FirebaseAppDistribution/*.h' - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.dependency 'GoogleUtilities/AppDelegateSwizzler', '~> 8.0' s.dependency 'GoogleUtilities/UserDefaults', '~> 8.0' s.dependency 'FirebaseInstallations', '~> 11.0' diff --git a/FirebaseAuth.podspec b/FirebaseAuth.podspec index 67f32a30b74..bdb9ee26263 100644 --- a/FirebaseAuth.podspec +++ b/FirebaseAuth.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAuth' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Apple platform client for Firebase Authentication' s.description = <<-DESC @@ -58,8 +58,8 @@ supports email and password accounts, as well as several 3rd party authenticatio s.ios.framework = 'SafariServices' s.dependency 'FirebaseAuthInterop', '~> 11.0' s.dependency 'FirebaseAppCheckInterop', '~> 11.0' - s.dependency 'FirebaseCore', '11.5' - s.dependency 'FirebaseCoreExtension', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' + s.dependency 'FirebaseCoreExtension', '~> 11.6.0' s.dependency 'GoogleUtilities/AppDelegateSwizzler', '~> 8.0' s.dependency 'GoogleUtilities/Environment', '~> 8.0' s.dependency 'GTMSessionFetcher/Core', '>= 3.4', '< 5.0' diff --git a/FirebaseAuth/Sources/Swift/Auth/Auth.swift b/FirebaseAuth/Sources/Swift/Auth/Auth.swift index 19e8029974b..e5ccdaafac7 100644 --- a/FirebaseAuth/Sources/Swift/Auth/Auth.swift +++ b/FirebaseAuth/Sources/Swift/Auth/Auth.swift @@ -123,11 +123,12 @@ extension Auth: AuthInterop { return } // Call back with current user token. - currentUser.internalGetToken(forceRefresh: forceRefresh) { token, error in - DispatchQueue.main.async { - callback(token, error) + currentUser + .internalGetToken(forceRefresh: forceRefresh, backend: strongSelf.backend) { token, error in + DispatchQueue.main.async { + callback(token, error) + } } - } } } @@ -292,7 +293,7 @@ extension Auth: AuthInterop { requestConfiguration: self.requestConfiguration) Task { do { - let response = try await AuthBackend.call(with: request) + let response = try await self.backend.call(with: request) Auth.wrapMainAsync(callback: completion, withParam: response.signinMethods, error: nil) } catch { Auth.wrapMainAsync(callback: completion, withParam: nil, error: error) @@ -395,7 +396,7 @@ extension Auth: AuthInterop { let response = try await injectRecaptcha(request: request, action: AuthRecaptchaAction.signInWithPassword) #else - let response = try await AuthBackend.call(with: request) + let response = try await backend.call(with: request) #endif return try await completeSignIn( withAccessToken: response.idToken, @@ -709,7 +710,7 @@ extension Auth: AuthInterop { let request = SignUpNewUserRequest(requestConfiguration: self.requestConfiguration) Task { do { - let response = try await AuthBackend.call(with: request) + let response = try await self.backend.call(with: request) let user = try await self.completeSignIn( withAccessToken: response.idToken, accessTokenExpirationDate: response.approximateExpirationDate, @@ -771,7 +772,7 @@ extension Auth: AuthInterop { requestConfiguration: self.requestConfiguration) Task { do { - let response = try await AuthBackend.call(with: request) + let response = try await self.backend.call(with: request) let user = try await self.completeSignIn( withAccessToken: response.idToken, accessTokenExpirationDate: response.approximateExpirationDate, @@ -881,7 +882,7 @@ extension Auth: AuthInterop { if let inResponse { response = inResponse } else { - response = try await AuthBackend.call(with: request) + response = try await self.backend.call(with: request) } let user = try await self.completeSignIn( withAccessToken: response.idToken, @@ -993,7 +994,7 @@ extension Auth: AuthInterop { requestConfiguration: self.requestConfiguration) Task { do { - let response = try await AuthBackend.call(with: request) + let response = try await self.backend.call(with: request) let operation = ActionCodeInfo.actionCodeOperation(forRequestType: response.requestType) guard let email = response.email else { @@ -1433,7 +1434,7 @@ extension Auth: AuthInterop { /// complete, or fails. Invoked asynchronously on the main thread in the future. @objc open func revokeToken(withAuthorizationCode authorizationCode: String, completion: ((Error?) -> Void)? = nil) { - currentUser?.internalGetToken { idToken, error in + currentUser?.internalGetToken(backend: backend) { idToken, error in if let error { Auth.wrapMainAsync(completion, error) return @@ -1613,7 +1614,9 @@ extension Auth: AuthInterop { // MARK: Internal methods - init(app: FirebaseApp, keychainStorageProvider: AuthKeychainStorage = AuthKeychainStorageReal()) { + init(app: FirebaseApp, + keychainStorageProvider: AuthKeychainStorage = AuthKeychainStorageReal(), + backend: AuthBackend = AuthBackend(rpcIssuer: AuthBackendRPCIssuer())) { Auth.setKeychainServiceNameForApp(app) self.app = app mainBundleUrlTypes = Bundle.main @@ -1638,6 +1641,7 @@ extension Auth: AuthInterop { auth: nil, heartbeatLogger: app.heartbeatLogger, appCheck: appCheck) + self.backend = backend super.init() requestConfiguration.auth = self @@ -1911,17 +1915,18 @@ extension Auth: AuthInterop { return } let uid = strongSelf.currentUser?.uid - strongSelf.currentUser?.internalGetToken(forceRefresh: true) { token, error in - if strongSelf.currentUser?.uid != uid { - return - } - if error != nil { - // Kicks off exponential back off logic to retry failed attempt. Starts with one minute - // delay (60 seconds) if this is the first failed attempt. - let rescheduleDelay = retry ? min(delay * 2, 16 * 60) : 60 - strongSelf.scheduleAutoTokenRefresh(withDelay: rescheduleDelay, retry: true) + strongSelf.currentUser? + .internalGetToken(forceRefresh: true, backend: strongSelf.backend) { token, error in + if strongSelf.currentUser?.uid != uid { + return + } + if error != nil { + // Kicks off exponential back off logic to retry failed attempt. Starts with one minute + // delay (60 seconds) if this is the first failed attempt. + let rescheduleDelay = retry ? min(delay * 2, 16 * 60) : 60 + strongSelf.scheduleAutoTokenRefresh(withDelay: rescheduleDelay, retry: true) + } } - } } } @@ -2075,7 +2080,7 @@ extension Auth: AuthInterop { requestConfiguration: requestConfiguration) request.autoCreate = !isReauthentication credential.prepare(request) - let response = try await AuthBackend.call(with: request) + let response = try await backend.call(with: request) if response.needConfirmation { let email = response.email let credential = OAuthCredential(withVerifyAssertionResponse: response) @@ -2114,7 +2119,7 @@ extension Auth: AuthInterop { phoneNumber: phoneNumber, operation: operation, requestConfiguration: requestConfiguration) - return try await AuthBackend.call(with: request) + return try await backend.call(with: request) case let .verification(verificationID, code): guard verificationID.count > 0 else { throw AuthErrorUtils.missingVerificationIDError(message: nil) @@ -2126,7 +2131,7 @@ extension Auth: AuthInterop { verificationCode: code, operation: operation, requestConfiguration: requestConfiguration) - return try await AuthBackend.call(with: request) + return try await backend.call(with: request) } } #endif @@ -2152,7 +2157,7 @@ extension Auth: AuthInterop { timestamp: credential.timestamp, displayName: credential.displayName, requestConfiguration: requestConfiguration) - let response = try await AuthBackend.call(with: request) + let response = try await backend.call(with: request) let user = try await completeSignIn(withAccessToken: response.idToken, accessTokenExpirationDate: response .approximateExpirationDate, @@ -2184,7 +2189,7 @@ extension Auth: AuthInterop { let request = EmailLinkSignInRequest(email: email, oobCode: actionCode, requestConfiguration: requestConfiguration) - let response = try await AuthBackend.call(with: request) + let response = try await backend.call(with: request) let user = try await completeSignIn(withAccessToken: response.idToken, accessTokenExpirationDate: response .approximateExpirationDate, @@ -2242,7 +2247,7 @@ extension Auth: AuthInterop { private func wrapAsyncRPCTask(_ request: any AuthRPCRequest, _ callback: ((Error?) -> Void)?) { Task { do { - let _ = try await AuthBackend.call(with: request) + let _ = try await self.backend.call(with: request) Auth.wrapMainAsync(callback, nil) } catch { Auth.wrapMainAsync(callback, error) @@ -2294,7 +2299,7 @@ extension Auth: AuthInterop { action: action) } else { do { - return try await AuthBackend.call(with: request) + return try await backend.call(with: request) } catch { let nsError = error as NSError if let underlyingError = nsError.userInfo[NSUnderlyingErrorKey] as? NSError, @@ -2313,7 +2318,7 @@ extension Auth: AuthInterop { } } } - return try await AuthBackend.call(with: request) + return try await backend.call(with: request) } #endif @@ -2330,6 +2335,8 @@ extension Auth: AuthInterop { /// Auth's backend. var requestConfiguration: AuthRequestConfiguration + let backend: AuthBackend + #if os(iOS) /// The manager for APNs tokens used by phone number auth. diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/AuthCredential.swift b/FirebaseAuth/Sources/Swift/AuthProvider/AuthCredential.swift index 0500875b10f..2ae683ae22b 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/AuthCredential.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/AuthCredential.swift @@ -16,7 +16,7 @@ import Foundation /// Public representation of a credential. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) -@objc(FIRAuthCredential) open class AuthCredential: NSObject { +@objc(FIRAuthCredential) open class AuthCredential: NSObject, @unchecked Sendable { /// The name of the identity provider for the credential. @objc public let provider: String diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/EmailAuthProvider.swift b/FirebaseAuth/Sources/Swift/AuthProvider/EmailAuthProvider.swift index 050dce30974..e87445b84a2 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/EmailAuthProvider.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/EmailAuthProvider.swift @@ -38,7 +38,8 @@ import Foundation } @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) -@objc(FIREmailPasswordAuthCredential) class EmailAuthCredential: AuthCredential, NSSecureCoding { +@objc(FIREmailPasswordAuthCredential) class EmailAuthCredential: AuthCredential, NSSecureCoding, + @unchecked Sendable { let email: String enum EmailType { diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/FacebookAuthProvider.swift b/FirebaseAuth/Sources/Swift/AuthProvider/FacebookAuthProvider.swift index cc89e7b3394..59cb2385425 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/FacebookAuthProvider.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/FacebookAuthProvider.swift @@ -34,7 +34,8 @@ import Foundation } @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) -@objc(FIRFacebookAuthCredential) class FacebookAuthCredential: AuthCredential, NSSecureCoding { +@objc(FIRFacebookAuthCredential) class FacebookAuthCredential: AuthCredential, NSSecureCoding, + @unchecked Sendable { let accessToken: String init(withAccessToken accessToken: String) { diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/GameCenterAuthProvider.swift b/FirebaseAuth/Sources/Swift/AuthProvider/GameCenterAuthProvider.swift index 4560bad9aaf..82836ee81b0 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/GameCenterAuthProvider.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/GameCenterAuthProvider.swift @@ -129,7 +129,7 @@ @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) @objc(FIRGameCenterAuthCredential) - class GameCenterAuthCredential: AuthCredential, NSSecureCoding { + class GameCenterAuthCredential: AuthCredential, NSSecureCoding, @unchecked Sendable { let playerID: String let teamPlayerID: String? let gamePlayerID: String? diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/GitHubAuthProvider.swift b/FirebaseAuth/Sources/Swift/AuthProvider/GitHubAuthProvider.swift index 801e63fa8ee..75b914cbb7a 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/GitHubAuthProvider.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/GitHubAuthProvider.swift @@ -34,7 +34,8 @@ import Foundation } @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) -@objc(FIRGitHubAuthCredential) class GitHubAuthCredential: AuthCredential, NSSecureCoding { +@objc(FIRGitHubAuthCredential) class GitHubAuthCredential: AuthCredential, NSSecureCoding, + @unchecked Sendable { let token: String init(withToken token: String) { diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/GoogleAuthProvider.swift b/FirebaseAuth/Sources/Swift/AuthProvider/GoogleAuthProvider.swift index 41f223b25dc..0f41ac69ce3 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/GoogleAuthProvider.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/GoogleAuthProvider.swift @@ -36,7 +36,8 @@ import Foundation } @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) -@objc(FIRGoogleAuthCredential) class GoogleAuthCredential: AuthCredential, NSSecureCoding { +@objc(FIRGoogleAuthCredential) class GoogleAuthCredential: AuthCredential, NSSecureCoding, + @unchecked Sendable { let idToken: String let accessToken: String diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/OAuthCredential.swift b/FirebaseAuth/Sources/Swift/AuthProvider/OAuthCredential.swift index 920fd138af4..8029fd6df51 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/OAuthCredential.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/OAuthCredential.swift @@ -16,7 +16,8 @@ import Foundation /// Internal implementation of `AuthCredential` for generic credentials. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) -@objc(FIROAuthCredential) open class OAuthCredential: AuthCredential, NSSecureCoding { +@objc(FIROAuthCredential) open class OAuthCredential: AuthCredential, NSSecureCoding, + @unchecked Sendable { /// The ID Token associated with this credential. @objc(IDToken) public let idToken: String? diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift b/FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift index 01437d49891..b8cca1f5fca 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift @@ -413,7 +413,7 @@ import Foundation private func getHeadfulLiteUrl(eventID: String, sessionID: String) async throws -> URL? { let authDomain = try await AuthWebUtils - .fetchAuthDomain(withRequestConfiguration: auth.requestConfiguration) + .fetchAuthDomain(withRequestConfiguration: auth.requestConfiguration, backend: auth.backend) let bundleID = Bundle.main.bundleIdentifier let clientID = auth.app?.options.clientID let appID = auth.app?.options.googleAppID diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/PhoneAuthCredential.swift b/FirebaseAuth/Sources/Swift/AuthProvider/PhoneAuthCredential.swift index 49f643a34d1..a930fadc2eb 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/PhoneAuthCredential.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/PhoneAuthCredential.swift @@ -18,7 +18,8 @@ import Foundation /// /// This class is available on iOS only. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) -@objc(FIRPhoneAuthCredential) open class PhoneAuthCredential: AuthCredential, NSSecureCoding { +@objc(FIRPhoneAuthCredential) open class PhoneAuthCredential: AuthCredential, NSSecureCoding, + @unchecked Sendable { enum CredentialKind { case phoneNumber(_ phoneNumber: String, _ temporaryProof: String) case verification(_ id: String, _ code: String) diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/PhoneAuthProvider.swift b/FirebaseAuth/Sources/Swift/AuthProvider/PhoneAuthProvider.swift index 32d15499f74..2a1de385aa4 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/PhoneAuthProvider.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/PhoneAuthProvider.swift @@ -217,7 +217,7 @@ import Foundation .requestConfiguration) do { - let response = try await AuthBackend.call(with: request) + let response = try await auth.backend.call(with: request) return response.verificationID } catch { return try await handleVerifyErrorWithRetry(error: error, @@ -245,7 +245,7 @@ import Foundation requestConfiguration: auth.requestConfiguration ) - let response = try await AuthBackend.call(with: request) + let response = try await auth.backend.call(with: request) return response.verificationID } guard let session else { @@ -263,7 +263,7 @@ import Foundation let request = StartMFAEnrollmentRequest(idToken: idToken, enrollmentInfo: startMFARequestInfo, requestConfiguration: auth.requestConfiguration) - let response = try await AuthBackend.call(with: request) + let response = try await auth.backend.call(with: request) return response.phoneSessionInfo?.sessionInfo } else { let request = StartMFASignInRequest(MFAPendingCredential: session.mfaPendingCredential, @@ -271,7 +271,7 @@ import Foundation signInInfo: startMFARequestInfo, requestConfiguration: auth.requestConfiguration) - let response = try await AuthBackend.call(with: request) + let response = try await auth.backend.call(with: request) return response.responseInfo?.sessionInfo } } catch { @@ -328,7 +328,7 @@ import Foundation isSandbox: token.type == AuthAPNSTokenType.sandbox, requestConfiguration: auth.requestConfiguration) do { - let verifyResponse = try await AuthBackend.call(with: request) + let verifyResponse = try await auth.backend.call(with: request) guard let receipt = verifyResponse.receipt, let timeout = verifyResponse.suggestedTimeOutDate?.timeIntervalSinceNow else { fatalError("Internal Auth Error: invalid VerifyClientResponse") @@ -436,7 +436,7 @@ import Foundation /// - Parameter eventID: The event ID used for this purpose. private func reCAPTCHAURL(withEventID eventID: String) async throws -> URL? { let authDomain = try await AuthWebUtils - .fetchAuthDomain(withRequestConfiguration: auth.requestConfiguration) + .fetchAuthDomain(withRequestConfiguration: auth.requestConfiguration, backend: auth.backend) let bundleID = Bundle.main.bundleIdentifier let clientID = auth.app?.options.clientID let appID = auth.app?.options.googleAppID diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/TwitterAuthProvider.swift b/FirebaseAuth/Sources/Swift/AuthProvider/TwitterAuthProvider.swift index 6364241188f..f9c32f9d5ad 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/TwitterAuthProvider.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/TwitterAuthProvider.swift @@ -35,7 +35,8 @@ import Foundation } @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) -@objc(FIRTwitterAuthCredential) class TwitterAuthCredential: AuthCredential, NSSecureCoding { +@objc(FIRTwitterAuthCredential) class TwitterAuthCredential: AuthCredential, NSSecureCoding, + @unchecked Sendable { let token: String let secret: String diff --git a/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift b/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift index 58fb6c4be80..85802392052 100644 --- a/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift +++ b/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift @@ -32,21 +32,7 @@ class AuthBackend: AuthBackendProtocol { return "FirebaseAuth.iOS/\(FirebaseVersion()) \(GTMFetcherStandardUserAgentString(nil))" } - static func call(with request: T) async throws -> T.Response { - return try await shared.call(with: request) - } - - static func setTestRPCIssuer(issuer: AuthBackendRPCIssuer) { - shared.rpcIssuer = issuer - } - - static func resetRPCIssuer() { - shared.rpcIssuer = AuthBackendRPCIssuer() - } - - private static let shared: AuthBackend = .init(rpcIssuer: AuthBackendRPCIssuer()) - - private var rpcIssuer: any AuthBackendRPCIssuerProtocol + private let rpcIssuer: any AuthBackendRPCIssuerProtocol init(rpcIssuer: any AuthBackendRPCIssuerProtocol) { self.rpcIssuer = rpcIssuer @@ -251,66 +237,74 @@ class AuthBackend: AuthBackendProtocol { } dictionary = decodedDictionary - var response = T.Response() + let responseResult = Result { + try T.Response(dictionary: dictionary) + } // At this point we either have an error with successfully decoded // details in the body, or we have a response which must pass further // validation before we know it's truly successful. We deal with the // case where we have an error with successfully decoded error details // first: - if error != nil { - if let errorDictionary = dictionary["error"] as? [String: AnyHashable] { - if let errorMessage = errorDictionary["message"] as? String { - if let clientError = Self.clientError( - withServerErrorMessage: errorMessage, - errorDictionary: errorDictionary, - response: response, - error: error - ) { - throw clientError + switch responseResult { + case let .success(response): + try propagateError(error, dictionary: dictionary, response: response) + // In case returnIDPCredential of a verifyAssertion request is set to + // @YES, the server may return a 200 with a response that may contain a + // server error. + if let verifyAssertionRequest = request as? VerifyAssertionRequest { + if verifyAssertionRequest.returnIDPCredential { + if let errorMessage = dictionary["errorMessage"] as? String { + if let clientError = Self.clientError( + withServerErrorMessage: errorMessage, + errorDictionary: dictionary, + response: response, + error: error + ) { + throw clientError + } } } - // Not a message we know, return the message directly. - throw AuthErrorUtils.unexpectedErrorResponse( - deserializedResponse: errorDictionary, - underlyingError: error - ) } - // No error message at all, return the decoded response. + return response + case let .failure(failure): + try propagateError(error, dictionary: dictionary, response: nil) throw AuthErrorUtils - .unexpectedErrorResponse(deserializedResponse: dictionary, underlyingError: error) + .RPCResponseDecodingError(deserializedResponse: dictionary, underlyingError: failure) } + } - // Finally, we try to populate the response object with the JSON values. - do { - try response.setFields(dictionary: dictionary) - } catch { - throw AuthErrorUtils - .RPCResponseDecodingError(deserializedResponse: dictionary, underlyingError: error) + private func propagateError(_ error: Error?, dictionary: [String: AnyHashable], + response: AuthRPCResponse?) throws { + guard let error else { + return } - // In case returnIDPCredential of a verifyAssertion request is set to - // @YES, the server may return a 200 with a response that may contain a - // server error. - if let verifyAssertionRequest = request as? VerifyAssertionRequest { - if verifyAssertionRequest.returnIDPCredential { - if let errorMessage = dictionary["errorMessage"] as? String { - if let clientError = Self.clientError( - withServerErrorMessage: errorMessage, - errorDictionary: dictionary, - response: response, - error: error - ) { - throw clientError - } + + if let errorDictionary = dictionary["error"] as? [String: AnyHashable] { + if let errorMessage = errorDictionary["message"] as? String { + if let clientError = Self.clientError( + withServerErrorMessage: errorMessage, + errorDictionary: errorDictionary, + response: response, + error: error + ) { + throw clientError } } + // Not a message we know, return the message directly. + throw AuthErrorUtils.unexpectedErrorResponse( + deserializedResponse: errorDictionary, + underlyingError: error + ) } - return response + // No error message at all, return the decoded response. + throw AuthErrorUtils + .unexpectedErrorResponse(deserializedResponse: dictionary, underlyingError: error) } private static func clientError(withServerErrorMessage serverErrorMessage: String, errorDictionary: [String: Any], - response: AuthRPCResponse, + response: AuthRPCResponse?, error: Error?) -> Error? { let split = serverErrorMessage.split(separator: ":") let shortErrorMessage = split.first?.trimmingCharacters(in: .whitespacesAndNewlines) diff --git a/FirebaseAuth/Sources/Swift/Backend/AuthRPCResponse.swift b/FirebaseAuth/Sources/Swift/Backend/AuthRPCResponse.swift index 0b7ea8a3a52..00d302e5775 100644 --- a/FirebaseAuth/Sources/Swift/Backend/AuthRPCResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/AuthRPCResponse.swift @@ -15,14 +15,11 @@ import Foundation protocol AuthRPCResponse: Sendable { - /// Bare initializer for a response. - init() - - /// Sets the response instance from the decoded JSON response. + /// Initializes the response instance from the decoded JSON response. /// - Parameter dictionary: The dictionary decoded from HTTP JSON response. /// - Parameter error: An out field for an error which occurred constructing the request. /// - Returns: Whether the operation was successful or not. - mutating func setFields(dictionary: [String: AnyHashable]) throws + init(dictionary: [String: AnyHashable]) throws /// This optional method allows response classes to create client errors given a short error /// message and a detail error message from the server. diff --git a/FirebaseAuth/Sources/Swift/Backend/IdentityToolkitRequest.swift b/FirebaseAuth/Sources/Swift/Backend/IdentityToolkitRequest.swift index 3ee424459a5..3a5d5a3b18a 100644 --- a/FirebaseAuth/Sources/Swift/Backend/IdentityToolkitRequest.swift +++ b/FirebaseAuth/Sources/Swift/Backend/IdentityToolkitRequest.swift @@ -19,7 +19,15 @@ private let kHttpProtocol = "http:" private let kEmulatorHostAndPrefixFormat = "%@/%@" -private var gAPIHost = "www.googleapis.com" +#if compiler(>=6) + /// Host for server API calls. This should be changed via + /// `IdentityToolkitRequest.setHost(_ host:)` for testing purposes only. + private nonisolated(unsafe) var gAPIHost = "www.googleapis.com" +#else + /// Host for server API calls. This should be changed via + /// `IdentityToolkitRequest.setHost(_ host:)` for testing purposes only. + private var gAPIHost = "www.googleapis.com" +#endif // compiler(>=6) private let kFirebaseAuthAPIHost = "www.googleapis.com" private let kIdentityPlatformAPIHost = "identitytoolkit.googleapis.com" diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/CreateAuthURIResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/CreateAuthURIResponse.swift index 019a92f4b90..66b1ad95023 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/CreateAuthURIResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/CreateAuthURIResponse.swift @@ -35,7 +35,7 @@ struct CreateAuthURIResponse: AuthRPCResponse { /// A list of sign-in methods available for the passed identifier. var signinMethods: [String] = [] - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { providerID = dictionary["providerId"] as? String authURI = dictionary["authUri"] as? String registered = dictionary["registered"] as? Bool ?? false diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/DeleteAccountResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/DeleteAccountResponse.swift index 4b6802dafb3..d3a34371caa 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/DeleteAccountResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/DeleteAccountResponse.swift @@ -18,5 +18,5 @@ import Foundation /// /// See https://developers.google.com/identity/toolkit/web/reference/relyingparty/deleteAccount struct DeleteAccountResponse: AuthRPCResponse { - mutating func setFields(dictionary: [String: AnyHashable]) throws {} + init(dictionary: [String: AnyHashable]) throws {} } diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/EmailLinkSignInResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/EmailLinkSignInResponse.swift index 608c38237cc..0fb80a8f9c2 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/EmailLinkSignInResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/EmailLinkSignInResponse.swift @@ -40,7 +40,7 @@ struct EmailLinkSignInResponse: AuthRPCResponse, AuthMFAResponse { /// Info on which multi-factor authentication providers are enabled. private(set) var mfaInfo: [AuthProtoMFAEnrollment]? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { email = dictionary["email"] as? String idToken = dictionary["idToken"] as? String isNewUser = dictionary["isNewUser"] as? Bool ?? false diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/GetAccountInfoResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/GetAccountInfoResponse.swift index e0f9c463959..4fb5795bcd5 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/GetAccountInfoResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/GetAccountInfoResponse.swift @@ -139,7 +139,7 @@ struct GetAccountInfoResponse: AuthRPCResponse { /// The requested users' profiles. var users: [Self.User]? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { guard let usersData = dictionary["users"] as? [[String: AnyHashable]] else { throw AuthErrorUtils.unexpectedResponse(deserializedResponse: dictionary) } diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/GetOOBConfirmationCodeResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/GetOOBConfirmationCodeResponse.swift index 91721fd659e..dcfba9d5212 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/GetOOBConfirmationCodeResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/GetOOBConfirmationCodeResponse.swift @@ -19,7 +19,7 @@ private let kOOBCodeKey = "oobCode" struct GetOOBConfirmationCodeResponse: AuthRPCResponse { var OOBCode: String? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { OOBCode = dictionary[kOOBCodeKey] as? String } } diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/GetProjectConfigResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/GetProjectConfigResponse.swift index b9fb18771b7..65091a46c7e 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/GetProjectConfigResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/GetProjectConfigResponse.swift @@ -19,7 +19,7 @@ struct GetProjectConfigResponse: AuthRPCResponse { var authorizedDomains: [String]? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { projectID = dictionary["projectId"] as? String if let authorizedDomains = dictionary["authorizedDomains"] as? String, let data = authorizedDomains.data(using: .utf8) { diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/GetRecaptchaConfigResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/GetRecaptchaConfigResponse.swift index b62bd84a695..327ff3751a2 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/GetRecaptchaConfigResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/GetRecaptchaConfigResponse.swift @@ -18,7 +18,7 @@ struct GetRecaptchaConfigResponse: AuthRPCResponse { private(set) var recaptchaKey: String? private(set) var enforcementState: [[String: String]]? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { recaptchaKey = dictionary["recaptchaKey"] as? String enforcementState = dictionary["recaptchaEnforcementState"] as? [[String: String]] } diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/Enroll/FinalizeMFAEnrollmentResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/Enroll/FinalizeMFAEnrollmentResponse.swift index bdd3ce89d31..595e3b45952 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/Enroll/FinalizeMFAEnrollmentResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/Enroll/FinalizeMFAEnrollmentResponse.swift @@ -21,7 +21,7 @@ struct FinalizeMFAEnrollmentResponse: AuthRPCResponse { private(set) var phoneSessionInfo: AuthProtoFinalizeMFAPhoneResponseInfo? private(set) var totpSessionInfo: AuthProtoFinalizeMFATOTPEnrollmentResponseInfo? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { idToken = dictionary["idToken"] as? String refreshToken = dictionary["refreshToken"] as? String diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/Enroll/StartMFAEnrollmentResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/Enroll/StartMFAEnrollmentResponse.swift index dadbb9a15be..7c91b54227c 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/Enroll/StartMFAEnrollmentResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/Enroll/StartMFAEnrollmentResponse.swift @@ -19,7 +19,7 @@ struct StartMFAEnrollmentResponse: AuthRPCResponse { private(set) var phoneSessionInfo: AuthProtoStartMFAPhoneResponseInfo? private(set) var totpSessionInfo: AuthProtoStartMFATOTPEnrollmentResponseInfo? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { if let data = dictionary["phoneSessionInfo"] as? [String: AnyHashable] { phoneSessionInfo = AuthProtoStartMFAPhoneResponseInfo(dictionary: data) } else if let data = dictionary["totpSessionInfo"] as? [String: AnyHashable] { diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/SignIn/FinalizeMFASignInResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/SignIn/FinalizeMFASignInResponse.swift index 032dab3ff86..850a969e6cd 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/SignIn/FinalizeMFASignInResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/SignIn/FinalizeMFASignInResponse.swift @@ -19,7 +19,7 @@ struct FinalizeMFASignInResponse: AuthRPCResponse { var IDToken: String? var refreshToken: String? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { IDToken = dictionary["idToken"] as? String refreshToken = dictionary["refreshToken"] as? String } diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/SignIn/StartMFASignInResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/SignIn/StartMFASignInResponse.swift index cc597172010..291821c58f9 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/SignIn/StartMFASignInResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/SignIn/StartMFASignInResponse.swift @@ -18,7 +18,7 @@ import Foundation struct StartMFASignInResponse: AuthRPCResponse { var responseInfo: AuthProtoStartMFAPhoneResponseInfo? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { if let data = dictionary["phoneResponseInfo"] as? [String: AnyHashable] { responseInfo = AuthProtoStartMFAPhoneResponseInfo(dictionary: data) } else { diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/Unenroll/WithdrawMFAResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/Unenroll/WithdrawMFAResponse.swift index 4744a6965ee..27bcd0d32e4 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/Unenroll/WithdrawMFAResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/MultiFactor/Unenroll/WithdrawMFAResponse.swift @@ -18,7 +18,7 @@ struct WithdrawMFAResponse: AuthRPCResponse { var idToken: String? var refreshToken: String? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { idToken = dictionary["idToken"] as? String refreshToken = dictionary["refreshToken"] as? String } diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/ResetPasswordResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/ResetPasswordResponse.swift index 22cb703e5ad..1744dfc34cf 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/ResetPasswordResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/ResetPasswordResponse.swift @@ -34,7 +34,7 @@ struct ResetPasswordResponse: AuthRPCResponse { /// The type of request as returned by the backend. var requestType: String? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { email = dictionary["email"] as? String requestType = dictionary["requestType"] as? String verifiedEmail = dictionary["newEmail"] as? String diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/RevokeTokenResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/RevokeTokenResponse.swift index 7e6bf0e7378..900959ccbe1 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/RevokeTokenResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/RevokeTokenResponse.swift @@ -15,7 +15,7 @@ import Foundation struct RevokeTokenResponse: AuthRPCResponse { - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { // Nothing to set or throw. } } diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/SecureTokenRequest.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/SecureTokenRequest.swift index c07d60c7a60..d11275dcf29 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/SecureTokenRequest.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/SecureTokenRequest.swift @@ -54,12 +54,19 @@ private let kRefreshTokenKey = "refreshToken" /// The key for the "code" parameter in the request. private let kCodeKey = "code" -/// Host for server API calls. -private var gAPIHost = "securetoken.googleapis.com" +#if compiler(>=6) + /// Host for server API calls. This should be changed via + /// `SecureTokenRequest.setHost(_ host:)` for testing purposes only. + private nonisolated(unsafe) var gAPIHost = "securetoken.googleapis.com" +#else + /// Host for server API calls. This should be changed via + /// `SecureTokenRequest.setHost(_ host:)` for testing purposes only. + private var gAPIHost = "securetoken.googleapis.com" +#endif // compiler(>=6) /// Represents the parameters for the token endpoint. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) -struct SecureTokenRequest: AuthRPCRequest { +class SecureTokenRequest: AuthRPCRequest { typealias Response = SecureTokenResponse /// The type of grant requested. diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/SecureTokenResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/SecureTokenResponse.swift index 86291a60015..44409ba92d4 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/SecureTokenResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/SecureTokenResponse.swift @@ -37,7 +37,7 @@ struct SecureTokenResponse: AuthRPCResponse { var expectedKind: String? { nil } - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { refreshToken = dictionary[kRefreshTokenKey] as? String self.accessToken = dictionary[kAccessTokenKey] as? String idToken = dictionary[kIDTokenKey] as? String diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/SendVerificationTokenResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/SendVerificationTokenResponse.swift index f9e6872cfcb..7b1815c5925 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/SendVerificationTokenResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/SendVerificationTokenResponse.swift @@ -17,7 +17,7 @@ import Foundation struct SendVerificationCodeResponse: AuthRPCResponse { var verificationID: String? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { verificationID = dictionary["sessionInfo"] as? String } } diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/SetAccountInfoResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/SetAccountInfoResponse.swift index c1b932b83c2..0a036d95195 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/SetAccountInfoResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/SetAccountInfoResponse.swift @@ -60,7 +60,7 @@ struct SetAccountInfoResponse: AuthRPCResponse { /// The refresh token from Secure Token Service. var refreshToken: String? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { email = dictionary["email"] as? String displayName = dictionary["displayName"] as? String idToken = dictionary["idToken"] as? String diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/SignInWithGameCenterResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/SignInWithGameCenterResponse.swift index d291384ff49..cc81610b17b 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/SignInWithGameCenterResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/SignInWithGameCenterResponse.swift @@ -25,7 +25,7 @@ struct SignInWithGameCenterResponse: AuthRPCResponse { var isNewUser: Bool = false var displayName: String? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { idToken = dictionary["idToken"] as? String refreshToken = dictionary["refreshToken"] as? String localID = dictionary["localId"] as? String diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/SignUpNewUserResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/SignUpNewUserResponse.swift index 7b25c6a6f8c..21f359b0f1a 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/SignUpNewUserResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/SignUpNewUserResponse.swift @@ -26,7 +26,7 @@ struct SignUpNewUserResponse: AuthRPCResponse { /// The refresh token from Secure Token Service. var refreshToken: String? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { idToken = dictionary["idToken"] as? String if let approximateExpirationDate = dictionary["expiresIn"] as? String { self diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyAssertionResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyAssertionResponse.swift index c031aa22c43..9caa9d38e35 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyAssertionResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyAssertionResponse.swift @@ -132,7 +132,7 @@ struct VerifyAssertionResponse: AuthRPCResponse, AuthMFAResponse { private(set) var mfaInfo: [AuthProtoMFAEnrollment]? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { federatedID = dictionary["federatedId"] as? String providerID = dictionary["providerId"] as? String localID = dictionary["localId"] as? String diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyCustomTokenResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyCustomTokenResponse.swift index 5c66bf6ba74..9cf1ec0924f 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyCustomTokenResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyCustomTokenResponse.swift @@ -30,7 +30,7 @@ struct VerifyCustomTokenResponse: AuthRPCResponse { /// Flag indicating that the user signing in is a new user and not a returning user. var isNewUser: Bool = false - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { idToken = dictionary["idToken"] as? String if let dateString = dictionary["expiresIn"] as? NSString { approximateExpirationDate = Date(timeIntervalSinceNow: dateString.doubleValue) diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyPasswordResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyPasswordResponse.swift index ba93ac1e0a5..22a3d87e958 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyPasswordResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyPasswordResponse.swift @@ -51,7 +51,7 @@ struct VerifyPasswordResponse: AuthRPCResponse, AuthMFAResponse { private(set) var mfaInfo: [AuthProtoMFAEnrollment]? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { localID = dictionary["localId"] as? String email = dictionary["email"] as? String displayName = dictionary["displayName"] as? String diff --git a/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyPhoneNumberResponse.swift b/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyPhoneNumberResponse.swift index b5efb964c73..a187824b7dd 100644 --- a/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyPhoneNumberResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/RPC/VerifyPhoneNumberResponse.swift @@ -43,7 +43,7 @@ struct VerifyPhoneNumberResponse: AuthRPCResponse { nil } - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { idToken = dictionary["idToken"] as? String refreshToken = dictionary["refreshToken"] as? String isNewUser = (dictionary["isNewUser"] as? Bool) ?? false diff --git a/FirebaseAuth/Sources/Swift/Backend/VerifyClientResponse.swift b/FirebaseAuth/Sources/Swift/Backend/VerifyClientResponse.swift index 683ed33a01f..a468197948f 100644 --- a/FirebaseAuth/Sources/Swift/Backend/VerifyClientResponse.swift +++ b/FirebaseAuth/Sources/Swift/Backend/VerifyClientResponse.swift @@ -15,15 +15,13 @@ import Foundation struct VerifyClientResponse: AuthRPCResponse { - init() {} - /// Receipt that the APNS token was successfully validated with APNS. private(set) var receipt: String? /// The date after which delivery of the silent push notification is considered to have failed. private(set) var suggestedTimeOutDate: Date? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { receipt = dictionary["receipt"] as? String let suggestedTimeout = dictionary["suggestedTimeout"] if let string = suggestedTimeout as? String, diff --git a/FirebaseAuth/Sources/Swift/MultiFactor/MultiFactor.swift b/FirebaseAuth/Sources/Swift/MultiFactor/MultiFactor.swift index f3dd5b26981..c60f353e362 100644 --- a/FirebaseAuth/Sources/Swift/MultiFactor/MultiFactor.swift +++ b/FirebaseAuth/Sources/Swift/MultiFactor/MultiFactor.swift @@ -88,7 +88,7 @@ import Foundation .requestConfiguration) Task { do { - let response = try await AuthBackend.call(with: request) + let response = try await auth.backend.call(with: request) do { let user = try await auth.completeSignIn(withAccessToken: response.idToken, accessTokenExpirationDate: nil, @@ -139,7 +139,7 @@ import Foundation Task { do { - let response = try await AuthBackend.call(with: request) + let response = try await auth.backend.call(with: request) do { let user = try await auth.completeSignIn(withAccessToken: response.idToken, accessTokenExpirationDate: nil, @@ -217,7 +217,7 @@ import Foundation requestConfiguration: user.requestConfiguration) Task { do { - let response = try await AuthBackend.call(with: request) + let response = try await auth.backend.call(with: request) do { let user = try await auth.completeSignIn(withAccessToken: response.idToken, accessTokenExpirationDate: nil, diff --git a/FirebaseAuth/Sources/Swift/MultiFactor/MultiFactorResolver.swift b/FirebaseAuth/Sources/Swift/MultiFactor/MultiFactorResolver.swift index 64b8bdda693..366ccc02023 100644 --- a/FirebaseAuth/Sources/Swift/MultiFactor/MultiFactorResolver.swift +++ b/FirebaseAuth/Sources/Swift/MultiFactor/MultiFactorResolver.swift @@ -72,7 +72,7 @@ import Foundation ) Task { do { - let response = try await AuthBackend.call(with: request) + let response = try await self.auth.backend.call(with: request) let user = try await self.auth.completeSignIn(withAccessToken: response.idToken, accessTokenExpirationDate: nil, refreshToken: response.refreshToken, diff --git a/FirebaseAuth/Sources/Swift/MultiFactor/TOTP/TOTPMultiFactorGenerator.swift b/FirebaseAuth/Sources/Swift/MultiFactor/TOTP/TOTPMultiFactorGenerator.swift index 4fc574caedb..bf3b07634ca 100644 --- a/FirebaseAuth/Sources/Swift/MultiFactor/TOTP/TOTPMultiFactorGenerator.swift +++ b/FirebaseAuth/Sources/Swift/MultiFactor/TOTP/TOTPMultiFactorGenerator.swift @@ -31,8 +31,7 @@ import Foundation @objc(generateSecretWithMultiFactorSession:completion:) open class func generateSecret(with session: MultiFactorSession, completion: @escaping (TOTPSecret?, Error?) -> Void) { - guard let currentUser = session.currentUser, - let requestConfiguration = currentUser.auth?.requestConfiguration else { + guard let currentUser = session.currentUser, let auth = currentUser.auth else { let error = AuthErrorUtils.error(code: AuthErrorCode.internalError, userInfo: [NSLocalizedDescriptionKey: "Invalid ID token."]) @@ -42,10 +41,10 @@ import Foundation let totpEnrollmentInfo = AuthProtoStartMFATOTPEnrollmentRequestInfo() let request = StartMFAEnrollmentRequest(idToken: session.idToken, totpEnrollmentInfo: totpEnrollmentInfo, - requestConfiguration: requestConfiguration) + requestConfiguration: auth.requestConfiguration) Task { do { - let response = try await AuthBackend.call(with: request) + let response = try await auth.backend.call(with: request) if let totpSessionInfo = response.totpSessionInfo { let secret = TOTPSecret(secretKey: totpSessionInfo.sharedSecretKey, hashingAlgorithm: totpSessionInfo.hashingAlgorithm, diff --git a/FirebaseAuth/Sources/Swift/SystemService/SecureTokenService.swift b/FirebaseAuth/Sources/Swift/SystemService/SecureTokenService.swift index dd9e6dbde13..6bdee4c395a 100644 --- a/FirebaseAuth/Sources/Swift/SystemService/SecureTokenService.swift +++ b/FirebaseAuth/Sources/Swift/SystemService/SecureTokenService.swift @@ -25,12 +25,13 @@ actor SecureTokenServiceInternal { /// - Parameter forceRefresh: Forces the token to be refreshed. /// - Returns : A tuple with the token and flag of whether it was updated. func fetchAccessToken(forcingRefresh forceRefresh: Bool, - service: SecureTokenService) async throws -> (String?, Bool) { + service: SecureTokenService, + backend: AuthBackend) async throws -> (String?, Bool) { if !forceRefresh, hasValidAccessToken(service: service) { return (service.accessToken, false) } else { AuthLog.logDebug(code: "I-AUT000017", message: "Fetching new token from backend.") - return try await requestAccessToken(retryIfExpired: true, service: service) + return try await requestAccessToken(retryIfExpired: true, service: service, backend: backend) } } @@ -41,7 +42,8 @@ actor SecureTokenServiceInternal { /// /// - Returns: Token and Bool indicating if update occurred. private func requestAccessToken(retryIfExpired: Bool, - service: SecureTokenService) async throws -> (String?, Bool) { + service: SecureTokenService, + backend: AuthBackend) async throws -> (String?, Bool) { // TODO: This was a crash in ObjC SDK, should it callback with an error? guard let refreshToken = service.refreshToken, let requestConfiguration = service.requestConfiguration else { @@ -50,7 +52,7 @@ actor SecureTokenServiceInternal { let request = SecureTokenRequest.refreshRequest(refreshToken: refreshToken, requestConfiguration: requestConfiguration) - let response = try await AuthBackend.call(with: request) + let response = try await backend.call(with: request) var tokenUpdated = false if let newAccessToken = response.accessToken, newAccessToken.count > 0, @@ -67,7 +69,11 @@ actor SecureTokenServiceInternal { if expirationDate.timeIntervalSinceNow <= kFiveMinutes { // We only retry once, to avoid an infinite loop in the case that an end-user has // their local time skewed by over an hour. - return try await requestAccessToken(retryIfExpired: false, service: service) + return try await requestAccessToken( + retryIfExpired: false, + service: service, + backend: backend + ) } } } @@ -152,8 +158,10 @@ class SecureTokenService: NSObject, NSSecureCoding { /// Invoked asynchronously on the auth global work queue in the future. /// - Parameter forceRefresh: Forces the token to be refreshed. /// - Returns : A tuple with the token and flag of whether it was updated. - func fetchAccessToken(forcingRefresh forceRefresh: Bool) async throws -> (String?, Bool) { - return try await internalService.fetchAccessToken(forcingRefresh: forceRefresh, service: self) + func fetchAccessToken(forcingRefresh forceRefresh: Bool, + backend: AuthBackend) async throws -> (String?, Bool) { + return try await internalService + .fetchAccessToken(forcingRefresh: forceRefresh, service: self, backend: backend) } // MARK: NSSecureCoding diff --git a/FirebaseAuth/Sources/Swift/User/User.swift b/FirebaseAuth/Sources/Swift/User/User.swift index 3371520bdf8..fccd96ab088 100644 --- a/FirebaseAuth/Sources/Swift/User/User.swift +++ b/FirebaseAuth/Sources/Swift/User/User.swift @@ -49,6 +49,9 @@ extension User: NSSecureCoding {} var providerDataRaw: [String: UserInfoImpl] + /// The backend service for the given instance. + private(set) var backend: AuthBackend + /// Metadata associated with the Firebase user in question. @objc public private(set) var metadata: UserMetadata @@ -583,7 +586,7 @@ extension User: NSSecureCoding {} open func getIDTokenResult(forcingRefresh: Bool, completion: ((AuthTokenResult?, Error?) -> Void)?) { kAuthGlobalWorkQueue.async { - self.internalGetToken(forceRefresh: forcingRefresh) { token, error in + self.internalGetToken(forceRefresh: forcingRefresh, backend: self.backend) { token, error in var tokenResult: AuthTokenResult? if let token { do { @@ -866,7 +869,7 @@ extension User: NSSecureCoding {} open func sendEmailVerification(with actionCodeSettings: ActionCodeSettings? = nil, completion: ((Error?) -> Void)? = nil) { kAuthGlobalWorkQueue.async { - self.internalGetToken { accessToken, error in + self.internalGetToken(backend: self.backend) { accessToken, error in if let error { User.callInMainThreadWithError(callback: completion, error: error) return @@ -884,7 +887,7 @@ extension User: NSSecureCoding {} ) Task { do { - let _ = try await AuthBackend.call(with: request) + let _ = try await self.backend.call(with: request) User.callInMainThreadWithError(callback: completion, error: nil) } catch { self.signOutIfTokenIsInvalid(withError: error) @@ -931,7 +934,7 @@ extension User: NSSecureCoding {} /// is complete, or fails. Invoked asynchronously on the main thread in the future. @objc open func delete(completion: ((Error?) -> Void)? = nil) { kAuthGlobalWorkQueue.async { - self.internalGetToken { accessToken, error in + self.internalGetToken(backend: self.backend) { accessToken, error in if let error { User.callInMainThreadWithError(callback: completion, error: error) return @@ -946,7 +949,7 @@ extension User: NSSecureCoding {} requestConfiguration: requestConfiguration) Task { do { - let _ = try await AuthBackend.call(with: request) + let _ = try await self.backend.call(with: request) try self.auth?.signOutByForce(withUserID: self.uid) User.callInMainThreadWithError(callback: completion, error: nil) } catch { @@ -996,7 +999,7 @@ extension User: NSSecureCoding {} actionCodeSettings: ActionCodeSettings? = nil, completion: ((Error?) -> Void)? = nil) { kAuthGlobalWorkQueue.async { - self.internalGetToken { accessToken, error in + self.internalGetToken(backend: self.backend) { accessToken, error in if let error { User.callInMainThreadWithError(callback: completion, error: error) return @@ -1015,7 +1018,7 @@ extension User: NSSecureCoding {} ) Task { do { - let _ = try await AuthBackend.call(with: request) + let _ = try await self.backend.call(with: request) User.callInMainThreadWithError(callback: completion, error: nil) } catch { User.callInMainThreadWithError(callback: completion, error: error) @@ -1054,7 +1057,8 @@ extension User: NSSecureCoding {} return tokenService.accessTokenExpirationDate } - init(withTokenService tokenService: SecureTokenService) { + init(withTokenService tokenService: SecureTokenService, backend: AuthBackend) { + self.backend = backend providerDataRaw = [:] userProfileUpdate = UserProfileUpdate() self.tokenService = tokenService @@ -1083,16 +1087,16 @@ extension User: NSSecureCoding {} accessToken: accessToken, accessTokenExpirationDate: accessTokenExpirationDate, refreshToken: refreshToken) - let user = User(withTokenService: tokenService) + let user = User(withTokenService: tokenService, backend: auth.backend) user.auth = auth user.tenantID = auth.tenantID user.requestConfiguration = auth.requestConfiguration - let accessToken2 = try await user.internalGetTokenAsync() + let accessToken2 = try await user.internalGetTokenAsync(backend: user.backend) let getAccountInfoRequest = GetAccountInfoRequest( accessToken: accessToken2, requestConfiguration: user.requestConfiguration ) - let response = try await AuthBackend.call(with: getAccountInfoRequest) + let response = try await auth.backend.call(with: getAccountInfoRequest) user.isAnonymous = anonymous user.update(withGetAccountInfoResponse: response) return user @@ -1137,12 +1141,13 @@ extension User: NSSecureCoding {} /// A weak reference to an `Auth` instance associated with this instance. weak var auth: Auth? { set { - _auth = newValue - guard let requestConfiguration = auth?.requestConfiguration else { - fatalError("Firebase Auth Internal Error: nil requestConfiguration when initializing User") + guard let newValue else { + fatalError("Firebase Auth Internal Error: Set user's auth property with non-nil instance.") } + _auth = newValue + requestConfiguration = newValue.requestConfiguration tokenService.requestConfiguration = requestConfiguration - self.requestConfiguration = requestConfiguration + backend = newValue.backend } get { return _auth } } @@ -1173,12 +1178,12 @@ extension User: NSSecureCoding {} // The list of providers need to be updated for the newly added email-password provider. Task { do { - let accessToken = try await self.internalGetTokenAsync() + let accessToken = try await self.internalGetTokenAsync(backend: self.backend) if let requestConfiguration = self.auth?.requestConfiguration { let getAccountInfoRequest = GetAccountInfoRequest(accessToken: accessToken, requestConfiguration: requestConfiguration) do { - let accountInfoResponse = try await AuthBackend.call(with: getAccountInfoRequest) + let accountInfoResponse = try await self.backend.call(with: getAccountInfoRequest) if let users = accountInfoResponse.users { for userAccountInfo in users { // Set the account to non-anonymous if there are any providers, even if @@ -1313,7 +1318,7 @@ extension User: NSSecureCoding {} private func internalUpdateOrLinkPhoneNumber(credential: PhoneAuthCredential, isLinkOperation: Bool, completion: @escaping (Error?) -> Void) { - internalGetToken { accessToken, error in + internalGetToken(backend: backend) { accessToken, error in if let error { completion(error) return @@ -1335,7 +1340,7 @@ extension User: NSSecureCoding {} request.accessToken = accessToken Task { do { - let verifyResponse = try await AuthBackend.call(with: request) + let verifyResponse = try await self.backend.call(with: request) guard let idToken = verifyResponse.idToken, let refreshToken = verifyResponse.refreshToken else { fatalError("Internal Auth Error: missing token in internalUpdateOrLinkPhoneNumber") @@ -1375,7 +1380,7 @@ extension User: NSSecureCoding {} password: String, authResult: AuthDataResult, _ completion: ((AuthDataResult?, Error?) -> Void)?) { - internalGetToken { accessToken, error in + internalGetToken(backend: backend) { accessToken, error in guard let requestConfiguration = self.auth?.requestConfiguration else { fatalError("Internal auth error: missing auth on User") } @@ -1394,7 +1399,7 @@ extension User: NSSecureCoding {} action: AuthRecaptchaAction .signUpPassword) #else - let response = try await AuthBackend.call(with: request) + let response = try await self.backend.call(with: request) #endif guard let refreshToken = response.refreshToken, let idToken = response.idToken else { @@ -1437,7 +1442,7 @@ extension User: NSSecureCoding {} let result = AuthDataResult(withUser: self, additionalUserInfo: nil) link(withEmail: emailCredential.email, password: password, authResult: result, completion) case let .link(link): - internalGetToken { accessToken, error in + internalGetToken(backend: backend) { accessToken, error in var queryItems = AuthWebUtils.parseURL(link) if link.count == 0 { if let urlComponents = URLComponents(string: link), @@ -1455,7 +1460,7 @@ extension User: NSSecureCoding {} request.idToken = accessToken Task { do { - let response = try await AuthBackend.call(with: request) + let response = try await self.backend.call(with: request) guard let idToken = response.idToken, let refreshToken = response.refreshToken else { fatalError("Internal Auth Error: missing token in EmailLinkSignInResponse") @@ -1484,7 +1489,7 @@ extension User: NSSecureCoding {} #if !os(watchOS) private func link(withGameCenterCredential gameCenterCredential: GameCenterAuthCredential, completion: ((AuthDataResult?, Error?) -> Void)?) { - internalGetToken { accessToken, error in + internalGetToken(backend: backend) { accessToken, error in guard let requestConfiguration = self.auth?.requestConfiguration, let publicKeyURL = gameCenterCredential.publicKeyURL, let signature = gameCenterCredential.signature, @@ -1503,7 +1508,7 @@ extension User: NSSecureCoding {} request.accessToken = accessToken Task { do { - let response = try await AuthBackend.call(with: request) + let response = try await self.backend.call(with: request) guard let idToken = response.idToken, let refreshToken = response.refreshToken else { fatalError("Internal Auth Error: missing token in link(withGameCredential") @@ -1584,10 +1589,11 @@ extension User: NSSecureCoding {} /// - Parameter callback: The block to invoke when the token is available. Invoked asynchronously /// on the global work thread in the future. func internalGetToken(forceRefresh: Bool = false, + backend: AuthBackend, callback: @escaping (String?, Error?) -> Void) { Task { do { - let token = try await internalGetTokenAsync(forceRefresh: forceRefresh) + let token = try await internalGetTokenAsync(forceRefresh: forceRefresh, backend: backend) callback(token, nil) } catch { callback(nil, error) @@ -1597,11 +1603,12 @@ extension User: NSSecureCoding {} /// Retrieves the Firebase authentication token, possibly refreshing it if it has expired. /// - Parameter forceRefresh - func internalGetTokenAsync(forceRefresh: Bool = false) async throws -> String { + func internalGetTokenAsync(forceRefresh: Bool = false, + backend: AuthBackend) async throws -> String { var keychainError = false do { let (token, tokenUpdated) = try await tokenService.fetchAccessToken( - forcingRefresh: forceRefresh + forcingRefresh: forceRefresh, backend: backend ) if tokenUpdated { if let error = updateKeychain() { @@ -1756,6 +1763,10 @@ extension User: NSSecureCoding {} ) as? String requestConfiguration = AuthRequestConfiguration(apiKey: apiKey ?? "", appID: appID ?? "") + // This property will be overwritten later via the `user.auth` property update. For now, a + // placeholder is set as the property update should happen right after this intializer. + backend = AuthBackend(rpcIssuer: AuthBackendRPCIssuer()) + userProfileUpdate = UserProfileUpdate() #if os(iOS) self.multiFactor = multiFactor ?? MultiFactor() diff --git a/FirebaseAuth/Sources/Swift/User/UserProfileUpdate.swift b/FirebaseAuth/Sources/Swift/User/UserProfileUpdate.swift index 74aa5cf5c73..0c51eb9fe83 100644 --- a/FirebaseAuth/Sources/Swift/User/UserProfileUpdate.swift +++ b/FirebaseAuth/Sources/Swift/User/UserProfileUpdate.swift @@ -18,13 +18,13 @@ import Foundation @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) actor UserProfileUpdate { func link(user: User, with credential: AuthCredential) async throws -> AuthDataResult { - let accessToken = try await user.internalGetTokenAsync() + let accessToken = try await user.internalGetTokenAsync(backend: user.backend) let request = VerifyAssertionRequest(providerID: credential.provider, requestConfiguration: user.requestConfiguration) credential.prepare(request) request.accessToken = accessToken do { - let response = try await AuthBackend.call(with: request) + let response = try await user.backend.call(with: request) guard let idToken = response.idToken, let refreshToken = response.refreshToken, let providerID = response.providerID else { @@ -48,7 +48,7 @@ actor UserProfileUpdate { } func unlink(user: User, fromProvider provider: String) async throws -> User { - let accessToken = try await user.internalGetTokenAsync() + let accessToken = try await user.internalGetTokenAsync(backend: user.backend) let request = SetAccountInfoRequest( accessToken: accessToken, requestConfiguration: user.requestConfiguration ) @@ -58,7 +58,7 @@ actor UserProfileUpdate { } request.deleteProviders = [provider] do { - let response = try await AuthBackend.call(with: request) + let response = try await user.backend.call(with: request) // We can't just use the provider info objects in SetAccountInfoResponse // because they don't have localID and email fields. Remove the specific @@ -105,7 +105,7 @@ actor UserProfileUpdate { SetAccountInfoRequest) -> Void) async throws { let userAccountInfo = try await getAccountInfoRefreshingCache(user) - let accessToken = try await user.internalGetTokenAsync() + let accessToken = try await user.internalGetTokenAsync(backend: user.backend) // Mutate setAccountInfoRequest in block let setAccountInfoRequest = @@ -115,7 +115,7 @@ actor UserProfileUpdate { ) changeBlock(userAccountInfo, setAccountInfoRequest) do { - let accountInfoResponse = try await AuthBackend.call(with: setAccountInfoRequest) + let accountInfoResponse = try await user.backend.call(with: setAccountInfoRequest) if let idToken = accountInfoResponse.idToken, let refreshToken = accountInfoResponse.refreshToken { let tokenService = SecureTokenService( @@ -143,13 +143,13 @@ actor UserProfileUpdate { accessTokenExpirationDate: expirationDate, refreshToken: refreshToken ) - let accessToken = try await user.internalGetTokenAsync() + let accessToken = try await user.internalGetTokenAsync(backend: user.backend) let getAccountInfoRequest = GetAccountInfoRequest( accessToken: accessToken, requestConfiguration: user.requestConfiguration ) do { - let response = try await AuthBackend.call(with: getAccountInfoRequest) + let response = try await user.backend.call(with: getAccountInfoRequest) user.isAnonymous = false user.update(withGetAccountInfoResponse: response) } catch { @@ -168,7 +168,7 @@ actor UserProfileUpdate { /// - Parameter tokenService: The new token service object. /// - Parameter callback: The block to be called in the global auth working queue once finished. func setTokenService(user: User, tokenService: SecureTokenService) async throws { - _ = try await tokenService.fetchAccessToken(forcingRefresh: false) + _ = try await tokenService.fetchAccessToken(forcingRefresh: false, backend: user.backend) user.tokenService = tokenService if let error = user.updateKeychain() { throw error @@ -180,11 +180,11 @@ actor UserProfileUpdate { /// error has been detected. Invoked asynchronously on the auth global work queue in the future. func getAccountInfoRefreshingCache(_ user: User) async throws -> GetAccountInfoResponse.User { - let token = try await user.internalGetTokenAsync() + let token = try await user.internalGetTokenAsync(backend: user.backend) let request = GetAccountInfoRequest(accessToken: token, requestConfiguration: user.requestConfiguration) do { - let accountInfoResponse = try await AuthBackend.call(with: request) + let accountInfoResponse = try await user.backend.call(with: request) user.update(withGetAccountInfoResponse: accountInfoResponse) if let error = user.updateKeychain() { throw error diff --git a/FirebaseAuth/Sources/Swift/Utilities/AuthDefaultUIDelegate.swift b/FirebaseAuth/Sources/Swift/Utilities/AuthDefaultUIDelegate.swift index 6e7a5b30a57..aa8d3cbec6b 100644 --- a/FirebaseAuth/Sources/Swift/Utilities/AuthDefaultUIDelegate.swift +++ b/FirebaseAuth/Sources/Swift/Utilities/AuthDefaultUIDelegate.swift @@ -26,10 +26,10 @@ /// /// This class should be used in the case that a UIDelegate was expected and necessary to /// continue a given flow, but none was provided. - class AuthDefaultUIDelegate: NSObject, AuthUIDelegate { + final class AuthDefaultUIDelegate: NSObject, AuthUIDelegate { /// Returns a default AuthUIDelegate object. /// - Returns: The default AuthUIDelegate object. - class func defaultUIDelegate() -> AuthUIDelegate? { + @MainActor static func defaultUIDelegate() -> AuthUIDelegate? { if GULAppEnvironmentUtil.isAppExtension() { // iOS App extensions should not call [UIApplication sharedApplication], even if // UIApplication responds to it. diff --git a/FirebaseAuth/Sources/Swift/Utilities/AuthRecaptchaVerifier.swift b/FirebaseAuth/Sources/Swift/Utilities/AuthRecaptchaVerifier.swift index 6919ac40807..859496fac82 100644 --- a/FirebaseAuth/Sources/Swift/Utilities/AuthRecaptchaVerifier.swift +++ b/FirebaseAuth/Sources/Swift/Utilities/AuthRecaptchaVerifier.swift @@ -44,7 +44,7 @@ } @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) - class AuthRecaptchaVerifier { + class AuthRecaptchaVerifier: @unchecked Sendable { private(set) weak var auth: Auth? private(set) var agentConfig: AuthRecaptchaConfig? private(set) var tenantConfigs: [String: AuthRecaptchaConfig] = [:] @@ -149,12 +149,12 @@ } } - guard let requestConfiguration = auth?.requestConfiguration else { + guard let auth = auth else { throw AuthErrorUtils.error(code: .recaptchaNotEnabled, message: "No requestConfiguration for Auth instance") } - let request = GetRecaptchaConfigRequest(requestConfiguration: requestConfiguration) - let response = try await AuthBackend.call(with: request) + let request = GetRecaptchaConfigRequest(requestConfiguration: auth.requestConfiguration) + let response = try await auth.backend.call(with: request) AuthLog.logInfo(code: "I-AUT000029", message: "reCAPTCHA config retrieval succeeded.") // Response's site key is of the format projects//keys/' guard let keys = response.recaptchaKey?.components(separatedBy: "/"), @@ -179,7 +179,7 @@ } let config = AuthRecaptchaConfig(siteKey: siteKey, enablementStatus: enablementStatus) - if let tenantID = auth?.tenantID { + if let tenantID = auth.tenantID { tenantConfigs[tenantID] = config } else { agentConfig = config diff --git a/FirebaseAuth/Sources/Swift/Utilities/AuthWebUtils.swift b/FirebaseAuth/Sources/Swift/Utilities/AuthWebUtils.swift index 2231c040023..69210b9326b 100644 --- a/FirebaseAuth/Sources/Swift/Utilities/AuthWebUtils.swift +++ b/FirebaseAuth/Sources/Swift/Utilities/AuthWebUtils.swift @@ -98,7 +98,8 @@ class AuthWebUtils { return urlComponents.first } - static func fetchAuthDomain(withRequestConfiguration requestConfiguration: AuthRequestConfiguration) + static func fetchAuthDomain(withRequestConfiguration requestConfiguration: AuthRequestConfiguration, + backend: AuthBackend) async throws -> String { if let emulatorHostAndPort = requestConfiguration.emulatorHostAndPort { // If we are using the auth emulator, we do not want to call the GetProjectConfig endpoint. @@ -107,7 +108,7 @@ class AuthWebUtils { } let request = GetProjectConfigRequest(requestConfiguration: requestConfiguration) - let response = try await AuthBackend.call(with: request) + let response = try await backend.call(with: request) // Look up an authorized domain ends with one of the supportedAuthDomains. // The sequence of supportedAuthDomains matters. ("firebaseapp.com", "web.app") diff --git a/FirebaseAuth/Tests/SampleSwift/AuthenticationExample/ViewControllers/AuthViewController.swift b/FirebaseAuth/Tests/SampleSwift/AuthenticationExample/ViewControllers/AuthViewController.swift index fdde2e0757d..e9567a69e9d 100644 --- a/FirebaseAuth/Tests/SampleSwift/AuthenticationExample/ViewControllers/AuthViewController.swift +++ b/FirebaseAuth/Tests/SampleSwift/AuthenticationExample/ViewControllers/AuthViewController.swift @@ -481,7 +481,7 @@ class AuthViewController: UIViewController, DataSourceProviderDelegate { Task { do { - let verifyResponse = try await AuthBackend.call(with: request) + let verifyResponse = try await AppManager.shared.auth().backend.call(with: request) guard let receipt = verifyResponse.receipt, let timeoutDate = verifyResponse.suggestedTimeOutDate else { @@ -510,7 +510,7 @@ class AuthViewController: UIViewController, DataSourceProviderDelegate { ) do { - _ = try await AuthBackend.call(with: request) + _ = try await AppManager.shared.auth().backend.call(with: request) print("Verify iOS client succeeded") } catch { print("Verify iOS Client failed: \(error.localizedDescription)") diff --git a/FirebaseAuth/Tests/Unit/AuthBackendTests.swift b/FirebaseAuth/Tests/Unit/AuthBackendTests.swift index a7a484a7d5d..5feaf239e3b 100644 --- a/FirebaseAuth/Tests/Unit/AuthBackendTests.swift +++ b/FirebaseAuth/Tests/Unit/AuthBackendTests.swift @@ -41,7 +41,7 @@ class AuthBackendTests: RPCBaseTests { let request = FakeRequest(withEncodingError: encodingError) do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -71,7 +71,7 @@ class AuthBackendTests: RPCBaseTests { func testBodyDataSerializationError() async throws { let request = FakeRequest(withRequestBody: ["unencodable": self]) do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -99,7 +99,7 @@ class AuthBackendTests: RPCBaseTests { try self.rpcIssuer.respond(withData: nil, error: responseError) } do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -131,7 +131,7 @@ class AuthBackendTests: RPCBaseTests { try self.rpcIssuer.respond(withData: data, error: responseError) } do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -168,7 +168,7 @@ class AuthBackendTests: RPCBaseTests { try self.rpcIssuer.respond(withData: data, error: nil) } do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -210,7 +210,7 @@ class AuthBackendTests: RPCBaseTests { try self.rpcIssuer.respond(withData: data, error: responseError) } do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -252,7 +252,7 @@ class AuthBackendTests: RPCBaseTests { try self.rpcIssuer.respond(withData: data, error: nil) } do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -287,7 +287,7 @@ class AuthBackendTests: RPCBaseTests { error: responseError) } do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -329,7 +329,7 @@ class AuthBackendTests: RPCBaseTests { ) } do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -356,7 +356,7 @@ class AuthBackendTests: RPCBaseTests { error: responseError) } do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -398,7 +398,7 @@ class AuthBackendTests: RPCBaseTests { error: responseError) } do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -436,7 +436,7 @@ class AuthBackendTests: RPCBaseTests { let _ = try self.rpcIssuer.respond(withJSON: [:], error: responseError) } do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -473,7 +473,7 @@ class AuthBackendTests: RPCBaseTests { try self.rpcIssuer.respond(serverErrorMessage: customErrorMessage, error: responseError) } do { - let _ = try await AuthBackend.call(with: FakeRequest(withRequestBody: [:])) + let _ = try await authBackend.call(with: FakeRequest(withRequestBody: [:])) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -497,7 +497,7 @@ class AuthBackendTests: RPCBaseTests { } do { let request = FakeDecodingErrorRequest(withRequestBody: [:]) - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Expected to throw") } catch { let rpcError = error as NSError @@ -528,7 +528,7 @@ class AuthBackendTests: RPCBaseTests { // value it was given. try self.rpcIssuer.respond(withJSON: [kTestKey: kTestValue]) } - let rpcResponse = try await AuthBackend.call(with: FakeRequest(withRequestBody: [:])) + let rpcResponse = try await authBackend.call(with: FakeRequest(withRequestBody: [:])) XCTAssertEqual(try XCTUnwrap(rpcResponse.receivedValue), kTestValue) } @@ -593,7 +593,7 @@ class AuthBackendTests: RPCBaseTests { // Force return from async post try self.rpcIssuer.respond(withJSON: [:]) } - _ = try? await AuthBackend.call(with: request) + _ = try? await authBackend.call(with: request) // Then let expectedHeader = HeartbeatLoggingTestUtils.nonEmptyHeartbeatsPayload.headerValue() @@ -620,7 +620,7 @@ class AuthBackendTests: RPCBaseTests { // Just force return from async call. try self.rpcIssuer.respond(withJSON: [:]) } - _ = try? await AuthBackend.call(with: request) + _ = try? await authBackend.call(with: request) let completeRequest = await rpcIssuer.completeRequest.value let headerValue = completeRequest.value(forHTTPHeaderField: "X-Firebase-AppCheck") @@ -650,7 +650,7 @@ class AuthBackendTests: RPCBaseTests { // Force return from async post try self.rpcIssuer.respond(withJSON: [:]) } - _ = try? await AuthBackend.call(with: request) + _ = try? await authBackend.call(with: request) // Then let completeRequest = await rpcIssuer.completeRequest.value @@ -713,7 +713,7 @@ class AuthBackendTests: RPCBaseTests { private struct FakeResponse: AuthRPCResponse { var receivedValue: String? - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { receivedValue = dictionary["TestKey"] as? String } } @@ -739,7 +739,7 @@ class AuthBackendTests: RPCBaseTests { } private struct FakeDecodingErrorResponse: AuthRPCResponse { - mutating func setFields(dictionary: [String: AnyHashable]) throws { + init(dictionary: [String: AnyHashable]) throws { throw NSError(domain: "dummy", code: -1) } } diff --git a/FirebaseAuth/Tests/Unit/AuthTests.swift b/FirebaseAuth/Tests/Unit/AuthTests.swift index 1167bf22ca2..f84eb33d70f 100644 --- a/FirebaseAuth/Tests/Unit/AuthTests.swift +++ b/FirebaseAuth/Tests/Unit/AuthTests.swift @@ -47,7 +47,8 @@ class AuthTests: RPCBaseTests { #endif // (os(macOS) && !FIREBASE_AUTH_TESTING_USE_MACOS_KEYCHAIN) || SWIFT_PACKAGE auth = Auth( app: FirebaseApp.app(name: name)!, - keychainStorageProvider: keychainStorageProvider + keychainStorageProvider: keychainStorageProvider, + backend: authBackend ) // Set authDispatcherCallback implementation in order to save the token refresh task for later diff --git a/FirebaseAuth/Tests/Unit/CreateAuthURITests.swift b/FirebaseAuth/Tests/Unit/CreateAuthURITests.swift index af1f54bce28..334091d21fd 100644 --- a/FirebaseAuth/Tests/Unit/CreateAuthURITests.swift +++ b/FirebaseAuth/Tests/Unit/CreateAuthURITests.swift @@ -75,7 +75,7 @@ class CreateAuthURITests: RPCBaseTests { rpcIssuer?.respondBlock = { try self.rpcIssuer?.respond(withJSON: [kAuthUriKey: kTestAuthUri]) } - let rpcResponse = try await AuthBackend.call(with: makeAuthURIRequest()) + let rpcResponse = try await authBackend.call(with: makeAuthURIRequest()) XCTAssertEqual(rpcResponse.authURI, kTestAuthUri) } @@ -89,7 +89,7 @@ class CreateAuthURITests: RPCBaseTests { .respond(withJSON: ["kind": kTestExpectedKind, "allProviders": [kTestProviderID1, kTestProviderID2]]) } - let rpcResponse = try await AuthBackend.call(with: makeAuthURIRequest()) + let rpcResponse = try await authBackend.call(with: makeAuthURIRequest()) XCTAssertEqual(rpcIssuer?.requestURL?.absoluteString, kExpectedAPIURL) XCTAssertEqual(rpcIssuer?.decodedRequest?["identifier"] as? String, kTestIdentifier) diff --git a/FirebaseAuth/Tests/Unit/DeleteAccountTests.swift b/FirebaseAuth/Tests/Unit/DeleteAccountTests.swift index ae213aa8464..a968a02e3e8 100644 --- a/FirebaseAuth/Tests/Unit/DeleteAccountTests.swift +++ b/FirebaseAuth/Tests/Unit/DeleteAccountTests.swift @@ -64,7 +64,7 @@ class DeleteAccountTests: RPCBaseTests { rpcIssuer?.respondBlock = { try self.rpcIssuer?.respond(withJSON: [:]) } - let rpcResponse = try await AuthBackend.call(with: makeDeleteAccountRequest()) + let rpcResponse = try await authBackend.call(with: makeDeleteAccountRequest()) XCTAssertNotNil(rpcResponse) } diff --git a/FirebaseAuth/Tests/Unit/EmailLinkSignInTests.swift b/FirebaseAuth/Tests/Unit/EmailLinkSignInTests.swift index 2cdd4943653..ce4b2dd57d5 100644 --- a/FirebaseAuth/Tests/Unit/EmailLinkSignInTests.swift +++ b/FirebaseAuth/Tests/Unit/EmailLinkSignInTests.swift @@ -65,7 +65,7 @@ class EmailLinkSignInTests: RPCBaseTests { XCTAssertNil(requestDictionary[self.kIDTokenKey]) try self.rpcIssuer?.respond(withJSON: [:]) // unblock the await } - let _ = try await AuthBackend.call(with: makeEmailLinkSignInRequest()) + let _ = try await authBackend.call(with: makeEmailLinkSignInRequest()) } /** @fn testEmailLinkRequestCreationOptional @@ -87,7 +87,7 @@ class EmailLinkSignInTests: RPCBaseTests { XCTAssertEqual(requestDictionary[self.kIDTokenKey], kTestIDToken) try self.rpcIssuer?.respond(withJSON: [:]) // unblock the await } - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) } func testEmailLinkSignInErrors() async throws { @@ -115,7 +115,7 @@ class EmailLinkSignInTests: RPCBaseTests { "expiresIn": "\(kTestTokenExpirationTimeInterval)", "refreshToken": kTestRefreshToken]) } - let response = try await AuthBackend.call(with: makeEmailLinkSignInRequest()) + let response = try await authBackend.call(with: makeEmailLinkSignInRequest()) XCTAssertEqual(response.idToken, kTestIDTokenResponse) XCTAssertEqual(response.email, kTestEmailResponse) diff --git a/FirebaseAuth/Tests/Unit/GetAccountInfoTests.swift b/FirebaseAuth/Tests/Unit/GetAccountInfoTests.swift index 87a294c0ef2..dff1e74936e 100644 --- a/FirebaseAuth/Tests/Unit/GetAccountInfoTests.swift +++ b/FirebaseAuth/Tests/Unit/GetAccountInfoTests.swift @@ -100,7 +100,7 @@ class GetAccountInfoTests: RPCBaseTests { rpcIssuer?.respondBlock = { try self.rpcIssuer?.respond(withJSON: ["users": usersIn]) } - let rpcResponse = try await AuthBackend.call(with: makeGetAccountInfoRequest()) + let rpcResponse = try await authBackend.call(with: makeGetAccountInfoRequest()) let users = try XCTUnwrap(rpcResponse.users) XCTAssertGreaterThan(users.count, 0) diff --git a/FirebaseAuth/Tests/Unit/GetOOBConfirmationCodeTests.swift b/FirebaseAuth/Tests/Unit/GetOOBConfirmationCodeTests.swift index b9fe798f57d..631bab3a723 100644 --- a/FirebaseAuth/Tests/Unit/GetOOBConfirmationCodeTests.swift +++ b/FirebaseAuth/Tests/Unit/GetOOBConfirmationCodeTests.swift @@ -199,7 +199,7 @@ class GetOOBConfirmationCodeTests: RPCBaseTests { rpcIssuer?.respondBlock = { try self.rpcIssuer?.respond(withJSON: [self.kOOBCodeKey: self.kTestOOBCode]) } - let response = try await AuthBackend.call(with: request()) + let response = try await authBackend.call(with: request()) XCTAssertEqual(response.OOBCode, kTestOOBCode) } } @@ -217,7 +217,7 @@ class GetOOBConfirmationCodeTests: RPCBaseTests { rpcIssuer?.respondBlock = { try self.rpcIssuer?.respond(withJSON: [:]) } - let response = try await AuthBackend.call(with: request()) + let response = try await authBackend.call(with: request()) XCTAssertNil(response.OOBCode) } } diff --git a/FirebaseAuth/Tests/Unit/GetProjectConfigTests.swift b/FirebaseAuth/Tests/Unit/GetProjectConfigTests.swift index 107a5c33b4f..6dbe4c644c6 100644 --- a/FirebaseAuth/Tests/Unit/GetProjectConfigTests.swift +++ b/FirebaseAuth/Tests/Unit/GetProjectConfigTests.swift @@ -60,7 +60,7 @@ class GetProjectConfigTests: RPCBaseTests { try self.rpcIssuer?.respond(withJSON: ["projectId": kTestProjectID, "authorizedDomains": [kTestDomain1, kTestDomain2]]) } - let rpcResponse = try await AuthBackend.call(with: makeGetProjectConfigRequest()) + let rpcResponse = try await authBackend.call(with: makeGetProjectConfigRequest()) XCTAssertEqual(rpcResponse.projectID, kTestProjectID) XCTAssertEqual(rpcResponse.authorizedDomains?.first, kTestDomain1) XCTAssertEqual(rpcResponse.authorizedDomains?[1], kTestDomain2) diff --git a/FirebaseAuth/Tests/Unit/GetRecaptchaConfigTests.swift b/FirebaseAuth/Tests/Unit/GetRecaptchaConfigTests.swift index df64689c7c0..75149c38d45 100644 --- a/FirebaseAuth/Tests/Unit/GetRecaptchaConfigTests.swift +++ b/FirebaseAuth/Tests/Unit/GetRecaptchaConfigTests.swift @@ -24,7 +24,7 @@ class GetRecaptchaConfigTests: RPCBaseTests { */ func testGetRecaptchaConfigRequest() async throws { let request = GetRecaptchaConfigRequest(requestConfiguration: makeRequestConfiguration()) - // let _ = try await AuthBackend.call(with: request) + // let _ = try await authBackend.call(with: request) XCTAssertFalse(request.containsPostBody) // Confirm that the request has no decoded body as it is get request. @@ -47,7 +47,7 @@ class GetRecaptchaConfigTests: RPCBaseTests { let request = GetRecaptchaConfigRequest(requestConfiguration: makeRequestConfiguration()) rpcIssuer.recaptchaSiteKey = kTestRecaptchaKey - let response = try await AuthBackend.call(with: request) + let response = try await authBackend.call(with: request) XCTAssertEqual(response.recaptchaKey, kTestRecaptchaKey) XCTAssertNil(response.enforcementState) } diff --git a/FirebaseAuth/Tests/Unit/OAuthProviderTests.swift b/FirebaseAuth/Tests/Unit/OAuthProviderTests.swift index 6f1ed895b0a..a5a330babf7 100644 --- a/FirebaseAuth/Tests/Unit/OAuthProviderTests.swift +++ b/FirebaseAuth/Tests/Unit/OAuthProviderTests.swift @@ -282,6 +282,10 @@ import FirebaseCore .replacingOccurrences(of: ")", with: "") FirebaseApp.configure(name: strippedName, options: options) OAuthProviderTests.auth = Auth.auth(app: FirebaseApp.app(name: strippedName)!) + OAuthProviderTests.auth = Auth( + app: FirebaseApp.app(name: strippedName)!, + backend: authBackend + ) OAuthProviderTests.auth?.mainBundleUrlTypes = [["CFBundleURLSchemes": [scheme]]] } diff --git a/FirebaseAuth/Tests/Unit/PhoneAuthProviderTests.swift b/FirebaseAuth/Tests/Unit/PhoneAuthProviderTests.swift index 0030c52776d..9a319ea9755 100644 --- a/FirebaseAuth/Tests/Unit/PhoneAuthProviderTests.swift +++ b/FirebaseAuth/Tests/Unit/PhoneAuthProviderTests.swift @@ -662,7 +662,7 @@ let strippedName = functionName.replacingOccurrences(of: "(", with: "") .replacingOccurrences(of: ")", with: "") FirebaseApp.configure(name: strippedName, options: options) - let auth = Auth.auth(app: FirebaseApp.app(name: strippedName)!) + let auth = Auth(app: FirebaseApp.app(name: strippedName)!, backend: authBackend) kAuthGlobalWorkQueue.sync { // Wait for Auth protectedDataInitialization to finish. diff --git a/FirebaseAuth/Tests/Unit/RPCBaseTests.swift b/FirebaseAuth/Tests/Unit/RPCBaseTests.swift index 009289a1b44..9a8f9026ea9 100644 --- a/FirebaseAuth/Tests/Unit/RPCBaseTests.swift +++ b/FirebaseAuth/Tests/Unit/RPCBaseTests.swift @@ -68,15 +68,16 @@ class RPCBaseTests: XCTestCase { let kTestIdentifier = "Identifier" var rpcIssuer: FakeBackendRPCIssuer! + var authBackend: AuthBackend! override func setUp() { rpcIssuer = FakeBackendRPCIssuer() - AuthBackend.setTestRPCIssuer(issuer: rpcIssuer) + authBackend = AuthBackend(rpcIssuer: rpcIssuer) } override func tearDown() { rpcIssuer = nil - AuthBackend.resetRPCIssuer() + authBackend = nil } /** @fn checkRequest @@ -99,7 +100,7 @@ class RPCBaseTests: XCTestCase { // Dummy response to unblock await. let _ = try self.rpcIssuer?.respond(withJSON: [:]) } - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) } /** @fn checkBackendError @@ -123,7 +124,7 @@ class RPCBaseTests: XCTestCase { } } do { - let _ = try await AuthBackend.call(with: request) + let _ = try await authBackend.call(with: request) XCTFail("Did not throw expected error") return } catch { diff --git a/FirebaseAuth/Tests/Unit/ResetPasswordTests.swift b/FirebaseAuth/Tests/Unit/ResetPasswordTests.swift index 7fd7f346d3d..a3220f3ee41 100644 --- a/FirebaseAuth/Tests/Unit/ResetPasswordTests.swift +++ b/FirebaseAuth/Tests/Unit/ResetPasswordTests.swift @@ -82,7 +82,7 @@ class ResetPasswordTests: RPCBaseTests { try self.rpcIssuer?.respond(withJSON: ["email": kTestEmail, "requestType": kExpectedResetPasswordRequestType]) } - let rpcResponse = try await AuthBackend.call(with: makeResetPasswordRequest()) + let rpcResponse = try await authBackend.call(with: makeResetPasswordRequest()) XCTAssertEqual(rpcResponse.email, kTestEmail) XCTAssertEqual(rpcResponse.requestType, kExpectedResetPasswordRequestType) diff --git a/FirebaseAuth/Tests/Unit/RevokeTokenTests.swift b/FirebaseAuth/Tests/Unit/RevokeTokenTests.swift index 945e1e1ee1b..f55f42514d7 100644 --- a/FirebaseAuth/Tests/Unit/RevokeTokenTests.swift +++ b/FirebaseAuth/Tests/Unit/RevokeTokenTests.swift @@ -53,7 +53,7 @@ class RevokeTokenTests: RPCBaseTests { rpcIssuer.respondBlock = { try self.rpcIssuer?.respond(withJSON: [:]) } - let rpcResponse = try await AuthBackend.call(with: makeRevokeTokenRequest()) + let rpcResponse = try await authBackend.call(with: makeRevokeTokenRequest()) XCTAssertNotNil(rpcResponse) } diff --git a/FirebaseAuth/Tests/Unit/SendVerificationCodeTests.swift b/FirebaseAuth/Tests/Unit/SendVerificationCodeTests.swift index aa5a30686b6..d6b4b42bc14 100644 --- a/FirebaseAuth/Tests/Unit/SendVerificationCodeTests.swift +++ b/FirebaseAuth/Tests/Unit/SendVerificationCodeTests.swift @@ -113,7 +113,7 @@ class SendVerificationCodeTests: RPCBaseTests { rpcIssuer.respondBlock = { try self.rpcIssuer?.respond(withJSON: [kVerificationIDKey: kFakeVerificationID]) } - let rpcResponse = try await AuthBackend.call(with: + let rpcResponse = try await authBackend.call(with: makeSendVerificationCodeRequest(CodeIdentity.recaptcha(kTestReCAPTCHAToken))) XCTAssertNotNil(rpcResponse) XCTAssertEqual(rpcResponse.verificationID, kFakeVerificationID) diff --git a/FirebaseAuth/Tests/Unit/SetAccountInfoTests.swift b/FirebaseAuth/Tests/Unit/SetAccountInfoTests.swift index 4efe951991a..037116982de 100644 --- a/FirebaseAuth/Tests/Unit/SetAccountInfoTests.swift +++ b/FirebaseAuth/Tests/Unit/SetAccountInfoTests.swift @@ -212,7 +212,7 @@ class SetAccountInfoTests: RPCBaseTests { kExpiresInKey: kTestExpiresIn, kRefreshTokenKey: kTestRefreshToken]) } - let response = try await AuthBackend.call(with: setAccountInfoRequest()) + let response = try await authBackend.call(with: setAccountInfoRequest()) XCTAssertEqual(response.providerUserInfo?.first?.photoURL?.absoluteString, kTestPhotoURL) XCTAssertEqual(response.idToken, kTestIDToken) XCTAssertEqual(response.refreshToken, kTestRefreshToken) diff --git a/FirebaseAuth/Tests/Unit/SignInWithGameCenterTests.swift b/FirebaseAuth/Tests/Unit/SignInWithGameCenterTests.swift index 3513e9212c8..515cbd13e87 100644 --- a/FirebaseAuth/Tests/Unit/SignInWithGameCenterTests.swift +++ b/FirebaseAuth/Tests/Unit/SignInWithGameCenterTests.swift @@ -99,7 +99,7 @@ class SignInWithGameCenterTests: RPCBaseTests { "displayName": kDisplayName, ]) } - let rpcResponse = try await AuthBackend.call(with: request) + let rpcResponse = try await authBackend.call(with: request) XCTAssertNotNil(rpcResponse) XCTAssertEqual(rpcResponse.idToken, kIDToken) diff --git a/FirebaseAuth/Tests/Unit/SignUpNewUserTests.swift b/FirebaseAuth/Tests/Unit/SignUpNewUserTests.swift index 74c271bff6e..a75f6263a79 100644 --- a/FirebaseAuth/Tests/Unit/SignUpNewUserTests.swift +++ b/FirebaseAuth/Tests/Unit/SignUpNewUserTests.swift @@ -82,7 +82,7 @@ class SignUpNewUserTests: RPCBaseTests { kRefreshTokenKey: kTestRefreshToken, ]) } - let rpcResponse = try await AuthBackend.call(with: makeSignUpNewUserRequest()) + let rpcResponse = try await authBackend.call(with: makeSignUpNewUserRequest()) XCTAssertEqual(rpcResponse.refreshToken, kTestRefreshToken) let expiresIn = try XCTUnwrap(rpcResponse.approximateExpirationDate?.timeIntervalSinceNow) XCTAssertEqual(expiresIn, 12345, accuracy: 0.1) diff --git a/FirebaseAuth/Tests/Unit/UserTests.swift b/FirebaseAuth/Tests/Unit/UserTests.swift index 77c1449792f..d1f305f7116 100644 --- a/FirebaseAuth/Tests/Unit/UserTests.swift +++ b/FirebaseAuth/Tests/Unit/UserTests.swift @@ -33,12 +33,13 @@ class UserTests: RPCBaseTests { let kVerificationID = "55432" let kPhoneNumber = "555-1234" - static var auth: Auth? + var auth: Auth? - override class func setUp() { + override func setUp() { + super.setUp() let options = FirebaseOptions(googleAppID: "0:0000000000000:ios:0000000000000000", gcmSenderID: "00000000000000000-00000000000-000000000") - options.apiKey = kFakeAPIKey + options.apiKey = Self.kFakeAPIKey options.projectID = "myUserProjectID" FirebaseApp.configure(name: "test-UserTests", options: options) #if (os(macOS) && !FIREBASE_AUTH_TESTING_USE_MACOS_KEYCHAIN) || SWIFT_PACKAGE @@ -48,13 +49,17 @@ class UserTests: RPCBaseTests { #endif // (os(macOS) && !FIREBASE_AUTH_TESTING_USE_MACOS_KEYCHAIN) || SWIFT_PACKAGE auth = Auth( app: FirebaseApp.app(name: "test-UserTests")!, - keychainStorageProvider: keychainStorageProvider + keychainStorageProvider: keychainStorageProvider, + backend: authBackend ) } override func tearDown() { // Verifies that no tasks are left suspended on the AuthSerialTaskQueue. - try? UserTests.auth?.signOut() + try? auth?.signOut() + auth = nil + FirebaseApp.resetApps() + super.tearDown() } /** @fn testUserPropertiesAndNSSecureCoding @@ -415,7 +420,7 @@ class UserTests: RPCBaseTests { // Email should not have changed on the client side. XCTAssertEqual(user.email, self.kEmail) // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -441,7 +446,7 @@ class UserTests: RPCBaseTests { // Email should not have changed on the client side. XCTAssertEqual(user.email, self.kEmail) // User is no longer signed in.. - XCTAssertNil(UserTests.auth?.currentUser) + XCTAssertNil(self.auth?.currentUser) expectation.fulfill() } } @@ -457,7 +462,7 @@ class UserTests: RPCBaseTests { func testUpdatePhoneSuccess() throws { setFakeGetAccountProvider() let expectation = self.expectation(description: #function) - let auth = try XCTUnwrap(UserTests.auth) + let auth = try XCTUnwrap(self.auth) signInWithEmailPasswordReturnFakeUser { user in do { self.rpcIssuer.respondBlock = { @@ -491,7 +496,7 @@ class UserTests: RPCBaseTests { func testUpdatePhoneNumberFailure() throws { setFakeGetAccountProvider() let expectation = self.expectation(description: #function) - let auth = try XCTUnwrap(UserTests.auth) + let auth = try XCTUnwrap(self.auth) signInWithEmailPasswordReturnFakeUser { user in do { self.rpcIssuer.respondBlock = { @@ -523,7 +528,7 @@ class UserTests: RPCBaseTests { func testUpdatePhoneNumberFailureAutoSignOut() throws { setFakeGetAccountProvider() let expectation = self.expectation(description: #function) - let auth = try XCTUnwrap(UserTests.auth) + let auth = try XCTUnwrap(self.auth) signInWithEmailPasswordReturnFakeUser { user in do { self.rpcIssuer.respondBlock = { @@ -540,7 +545,7 @@ class UserTests: RPCBaseTests { let error = try! XCTUnwrap(rawError) XCTAssertEqual((error as NSError).code, AuthErrorCode.userTokenExpired.rawValue) // User is no longer signed in. - XCTAssertNil(UserTests.auth?.currentUser) + XCTAssertNil(self.auth?.currentUser) expectation.fulfill() } } @@ -579,7 +584,7 @@ class UserTests: RPCBaseTests { // Email should not have changed on the client side. XCTAssertEqual(user.email, self.kEmail) // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -605,7 +610,7 @@ class UserTests: RPCBaseTests { // Email should not have changed on the client side. XCTAssertEqual(user.email, self.kEmail) // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -632,7 +637,7 @@ class UserTests: RPCBaseTests { // Email should not have changed on the client side. XCTAssertEqual(user.email, self.kEmail) // User is signed out. - XCTAssertNil(UserTests.auth?.currentUser) + XCTAssertNil(self.auth?.currentUser) expectation.fulfill() } } @@ -688,7 +693,7 @@ class UserTests: RPCBaseTests { XCTAssertEqual(user.email, self.kEmail) XCTAssertEqual(user.displayName, self.kDisplayName) // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -716,7 +721,7 @@ class UserTests: RPCBaseTests { // Email should not have changed on the client side. XCTAssertEqual(user.email, self.kEmail) // User is signed out. - XCTAssertNil(UserTests.auth?.currentUser) + XCTAssertNil(self.auth?.currentUser) expectation.fulfill() } } @@ -821,7 +826,7 @@ class UserTests: RPCBaseTests { let error = try! XCTUnwrap(rawError) XCTAssertEqual((error as NSError).code, AuthErrorCode.quotaExceeded.rawValue) // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -848,7 +853,7 @@ class UserTests: RPCBaseTests { let error = try! XCTUnwrap(rawError) XCTAssertEqual((error as NSError).code, AuthErrorCode.userTokenExpired.rawValue) // User is no longer signed in. - XCTAssertNil(UserTests.auth?.currentUser) + XCTAssertNil(self.auth?.currentUser) expectation.fulfill() } } @@ -878,7 +883,7 @@ class UserTests: RPCBaseTests { XCTAssertEqual(result.user.email, user.email) XCTAssertEqual(result.additionalUserInfo?.isNewUser, false) // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -914,7 +919,7 @@ class UserTests: RPCBaseTests { } XCTAssertNil(error) // Verify that the current user is unchanged. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) // Verify that the current user and reauthenticated user are not same pointers. XCTAssertNotEqual(user, reauthenticatedAuthResult?.user) // Verify that anyway the current user and reauthenticated user have same IDs. @@ -933,7 +938,7 @@ class UserTests: RPCBaseTests { } } waitForExpectations(timeout: 5) - try assertUserGoogle(UserTests.auth?.currentUser) + try assertUserGoogle(auth?.currentUser) } /** @fn testReauthenticateFailure @@ -958,7 +963,7 @@ class UserTests: RPCBaseTests { // Email should not have changed on the client side. XCTAssertEqual(user.email, self.kEmail) // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -987,7 +992,7 @@ class UserTests: RPCBaseTests { // Email should not have changed on the client side. XCTAssertEqual(user.email, self.kEmail) // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -1001,7 +1006,7 @@ class UserTests: RPCBaseTests { func testLinkAndRetrieveDataSuccess() throws { setFakeGetAccountProvider() let expectation = self.expectation(description: #function) - let auth = try XCTUnwrap(UserTests.auth) + let auth = try XCTUnwrap(self.auth) signInWithFacebookCredential { user in XCTAssertNotNil(user) do { @@ -1069,7 +1074,7 @@ class UserTests: RPCBaseTests { // Email should not have changed on the client side. XCTAssertEqual(user.email, self.kFacebookEmail) // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -1100,7 +1105,7 @@ class UserTests: RPCBaseTests { XCTFail("Expected to throw providerAlreadyLinked error.") } // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -1130,7 +1135,7 @@ class UserTests: RPCBaseTests { let error = try! XCTUnwrap(rawError) XCTAssertEqual((error as NSError).code, AuthErrorCode.userDisabled.rawValue) // User is signed out. - XCTAssertNil(UserTests.auth?.currentUser) + XCTAssertNil(self.auth?.currentUser) expectation.fulfill() } } @@ -1145,7 +1150,7 @@ class UserTests: RPCBaseTests { func testLinkEmailAndRetrieveDataSuccess() throws { setFakeGetAccountProvider() let expectation = self.expectation(description: #function) - let auth = try XCTUnwrap(UserTests.auth) + let auth = try XCTUnwrap(self.auth) signInWithFacebookCredential { user in XCTAssertNotNil(user) do { @@ -1213,7 +1218,7 @@ class UserTests: RPCBaseTests { XCTFail("Expected to throw providerAlreadyLinked error.") } // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -1247,7 +1252,7 @@ class UserTests: RPCBaseTests { let error = try! XCTUnwrap(rawError) XCTAssertEqual((error as NSError).code, AuthErrorCode.tooManyRequests.rawValue) // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -1277,7 +1282,7 @@ class UserTests: RPCBaseTests { let error = try! XCTUnwrap(rawError) XCTAssertEqual((error as NSError).code, AuthErrorCode.userTokenExpired.rawValue) // User is signed out. - XCTAssertNil(UserTests.auth?.currentUser) + XCTAssertNil(self.auth?.currentUser) expectation.fulfill() } } @@ -1307,7 +1312,7 @@ class UserTests: RPCBaseTests { func testLinkProviderFailure() throws { setFakeGetAccountProvider() let expectation = self.expectation(description: #function) - let auth = try XCTUnwrap(UserTests.auth) + let auth = try XCTUnwrap(self.auth) signInWithFacebookCredential { user in XCTAssertNotNil(user) do { @@ -1322,7 +1327,7 @@ class UserTests: RPCBaseTests { let error = try! XCTUnwrap(rawError) XCTAssertEqual((error as NSError).code, AuthErrorCode.userTokenExpired.rawValue) // User is signed out. - XCTAssertNil(UserTests.auth?.currentUser) + XCTAssertNil(self.auth?.currentUser) expectation.fulfill() } } @@ -1336,7 +1341,7 @@ class UserTests: RPCBaseTests { func testReauthenticateWithProviderFailure() throws { setFakeGetAccountProvider() let expectation = self.expectation(description: #function) - let auth = try XCTUnwrap(UserTests.auth) + let auth = try XCTUnwrap(self.auth) signInWithFacebookCredential { user in XCTAssertNotNil(user) do { @@ -1351,7 +1356,7 @@ class UserTests: RPCBaseTests { let error = try! XCTUnwrap(rawError) XCTAssertEqual((error as NSError).code, AuthErrorCode.userTokenExpired.rawValue) // User is still signed in. - XCTAssertEqual(UserTests.auth?.currentUser, user) + XCTAssertEqual(self.auth?.currentUser, user) expectation.fulfill() } } @@ -1365,7 +1370,7 @@ class UserTests: RPCBaseTests { func testLinkPhoneAuthCredentialSuccess() throws { setFakeGetAccountProvider() let expectation = self.expectation(description: #function) - let auth = try XCTUnwrap(UserTests.auth) + let auth = try XCTUnwrap(self.auth) signInWithEmailPasswordReturnFakeUser { user in XCTAssertNotNil(user) self.expectVerifyPhoneNumberRequest(isLink: true) @@ -1410,7 +1415,7 @@ class UserTests: RPCBaseTests { func testUnlinkPhoneAuthCredentialSuccess() throws { setFakeGetAccountProvider() let expectation = self.expectation(description: #function) - let auth = try XCTUnwrap(UserTests.auth) + let auth = try XCTUnwrap(self.auth) signInWithEmailPasswordReturnFakeUser { user in XCTAssertNotNil(user) self.expectVerifyPhoneNumberRequest(isLink: true) @@ -1506,7 +1511,7 @@ class UserTests: RPCBaseTests { func testlinkPhoneCredentialAlreadyExistsError() throws { setFakeGetAccountProvider() let expectation = self.expectation(description: #function) - let auth = try XCTUnwrap(UserTests.auth) + let auth = try XCTUnwrap(self.auth) signInWithEmailPasswordReturnFakeUser { user in XCTAssertNotNil(user) self.expectVerifyPhoneNumberRequest(isLink: true) @@ -1668,12 +1673,12 @@ class UserTests: RPCBaseTests { } // 1. After setting up fakes, sign out and sign in. do { - try UserTests.auth?.signOut() + try auth?.signOut() } catch { XCTFail("Sign out failed: \(error)") return } - UserTests.auth?.signIn(withEmail: kEmail, password: kFakePassword) { authResult, error in + auth?.signIn(withEmail: kEmail, password: kFakePassword) { authResult, error in // 4. After the response triggers the callback, verify the returned result. XCTAssertTrue(Thread.isMainThread) guard let user = authResult?.user else { @@ -1716,10 +1721,10 @@ class UserTests: RPCBaseTests { } do { - try UserTests.auth?.signOut() + try auth?.signOut() let googleCredential = GoogleAuthProvider.credential(withIDToken: kGoogleIDToken, accessToken: kGoogleAccessToken) - UserTests.auth?.signIn(with: googleCredential) { authResult, error in + auth?.signIn(with: googleCredential) { authResult, error in // 4. After the response triggers the callback, verify the returned result. XCTAssertTrue(Thread.isMainThread) guard let user = authResult?.user else { @@ -1783,10 +1788,10 @@ class UserTests: RPCBaseTests { } do { - try UserTests.auth?.signOut() + try auth?.signOut() let facebookCredential = FacebookAuthProvider .credential(withAccessToken: kFacebookAccessToken) - UserTests.auth?.signIn(with: facebookCredential) { authResult, error in + auth?.signIn(with: facebookCredential) { authResult, error in // 4. After the response triggers the callback, verify the returned result. XCTAssertTrue(Thread.isMainThread) guard let user = authResult?.user else { @@ -1838,8 +1843,8 @@ class UserTests: RPCBaseTests { } do { - try UserTests.auth?.signOut() - UserTests.auth?.signIn( + try auth?.signOut() + auth?.signIn( withEmail: kEmail, link: "https://www.google.com?oobCode=aCode&mode=signIn" ) { authResult, error in diff --git a/FirebaseAuth/Tests/Unit/VerifyAssertionTests.swift b/FirebaseAuth/Tests/Unit/VerifyAssertionTests.swift index 95e131a8760..2fb630a62ce 100644 --- a/FirebaseAuth/Tests/Unit/VerifyAssertionTests.swift +++ b/FirebaseAuth/Tests/Unit/VerifyAssertionTests.swift @@ -180,7 +180,7 @@ class VerifyAssertionTests: RPCBaseTests { self.kRawUserInfoKey: self.profile, ]) } - let rpcResponse = try await AuthBackend.call(with: makeVerifyAssertionRequest()) + let rpcResponse = try await authBackend.call(with: makeVerifyAssertionRequest()) XCTAssertEqual(rpcResponse.idToken, kTestIDToken) XCTAssertEqual(rpcResponse.refreshToken, kTestRefreshToken) XCTAssertEqual(rpcResponse.verifiedProvider, [kTestProvider]) @@ -211,7 +211,7 @@ class VerifyAssertionTests: RPCBaseTests { self.kRawUserInfoKey: self.convertToJson(self.profile), ]) } - let rpcResponse = try await AuthBackend.call(with: makeVerifyAssertionRequest()) + let rpcResponse = try await authBackend.call(with: makeVerifyAssertionRequest()) XCTAssertEqual(rpcResponse.idToken, kTestIDToken) XCTAssertEqual(rpcResponse.refreshToken, kTestRefreshToken) XCTAssertEqual(rpcResponse.verifiedProvider, [kTestProvider]) diff --git a/FirebaseAuth/Tests/Unit/VerifyClientTests.swift b/FirebaseAuth/Tests/Unit/VerifyClientTests.swift index 0f7b0c792ca..528cb357c88 100644 --- a/FirebaseAuth/Tests/Unit/VerifyClientTests.swift +++ b/FirebaseAuth/Tests/Unit/VerifyClientTests.swift @@ -71,7 +71,7 @@ class VerifyClientTests: RPCBaseTests { kSuggestedTimeOutKey: kFakeSuggestedTimeout, ]) } - let rpcResponse = try await AuthBackend.call(with: makeVerifyClientRequest()) + let rpcResponse = try await authBackend.call(with: makeVerifyClientRequest()) XCTAssertEqual(rpcResponse.receipt, kFakeReceipt) let timeOut = try XCTUnwrap(rpcResponse.suggestedTimeOutDate?.timeIntervalSinceNow) XCTAssertEqual(timeOut, 1234, accuracy: 0.1) diff --git a/FirebaseAuth/Tests/Unit/VerifyCustomTokenTests.swift b/FirebaseAuth/Tests/Unit/VerifyCustomTokenTests.swift index 36fb06d13e6..8e3e052a4b2 100644 --- a/FirebaseAuth/Tests/Unit/VerifyCustomTokenTests.swift +++ b/FirebaseAuth/Tests/Unit/VerifyCustomTokenTests.swift @@ -107,7 +107,7 @@ class VerifyCustomTokenTests: RPCBaseTests { kIsNewUserKey: true, ]) } - let rpcResponse = try await AuthBackend.call(with: makeVerifyCustomTokenRequest()) + let rpcResponse = try await authBackend.call(with: makeVerifyCustomTokenRequest()) XCTAssertEqual(rpcResponse.idToken, kTestIDToken) XCTAssertEqual(rpcResponse.refreshToken, kTestRefreshToken) let expiresIn = try XCTUnwrap(rpcResponse.approximateExpirationDate?.timeIntervalSinceNow) diff --git a/FirebaseAuth/Tests/Unit/VerifyPasswordTests.swift b/FirebaseAuth/Tests/Unit/VerifyPasswordTests.swift index 6b831f0ce80..06821bf74c2 100644 --- a/FirebaseAuth/Tests/Unit/VerifyPasswordTests.swift +++ b/FirebaseAuth/Tests/Unit/VerifyPasswordTests.swift @@ -171,7 +171,7 @@ class VerifyPasswordTests: RPCBaseTests { kPhotoUrlKey: kTestPhotoUrl, ]) } - let rpcResponse = try await AuthBackend.call(with: makeVerifyPasswordRequest()) + let rpcResponse = try await authBackend.call(with: makeVerifyPasswordRequest()) XCTAssertEqual(rpcResponse.email, kTestEmail) XCTAssertEqual(rpcResponse.localID, kTestLocalID) XCTAssertEqual(rpcResponse.displayName, kTestDisplayName) diff --git a/FirebaseAuth/Tests/Unit/VerifyPhoneNumberTests.swift b/FirebaseAuth/Tests/Unit/VerifyPhoneNumberTests.swift index e6ff2a42434..50fb9cf67e5 100644 --- a/FirebaseAuth/Tests/Unit/VerifyPhoneNumberTests.swift +++ b/FirebaseAuth/Tests/Unit/VerifyPhoneNumberTests.swift @@ -116,7 +116,7 @@ import XCTest "isNewUser": true, ]) } - let rpcResponse = try await AuthBackend.call(with: makeVerifyPhoneNumberRequest()) + let rpcResponse = try await authBackend.call(with: makeVerifyPhoneNumberRequest()) XCTAssertEqual(rpcResponse.localID, kTestLocalID) XCTAssertEqual(rpcResponse.idToken, kTestIDToken) let expiresIn = try XCTUnwrap(rpcResponse.approximateExpirationDate?.timeIntervalSinceNow) @@ -135,7 +135,7 @@ import XCTest ]) } do { - let _ = try await AuthBackend.call(with: makeVerifyPhoneNumberRequestWithTemporaryProof()) + let _ = try await authBackend.call(with: makeVerifyPhoneNumberRequestWithTemporaryProof()) XCTFail("Expected to throw") } catch { let rpcError = error as NSError diff --git a/FirebaseAuthInterop.podspec b/FirebaseAuthInterop.podspec index 91dbd50ff5b..872de49ce94 100644 --- a/FirebaseAuthInterop.podspec +++ b/FirebaseAuthInterop.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAuthInterop' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Interfaces that allow other Firebase SDKs to use Auth functionality.' s.description = <<-DESC diff --git a/FirebaseCombineSwift.podspec b/FirebaseCombineSwift.podspec index a181b9b1a42..877521ac9a4 100644 --- a/FirebaseCombineSwift.podspec +++ b/FirebaseCombineSwift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCombineSwift' - s.version = '11.0.0' + s.version = '11.6.0' s.summary = 'Swift extensions with Combine support for Firebase' s.description = <<-DESC @@ -51,7 +51,7 @@ for internal testing only. It should not be published. s.osx.framework = 'AppKit' s.tvos.framework = 'UIKit' - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.dependency 'FirebaseAuth', '~> 11.0' s.dependency 'FirebaseFunctions', '~> 11.0' s.dependency 'FirebaseFirestore', '~> 11.0' diff --git a/FirebaseCore.podspec b/FirebaseCore.podspec index c2ccb23fddc..0587b7c19e2 100644 --- a/FirebaseCore.podspec +++ b/FirebaseCore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCore' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase Core' s.description = <<-DESC @@ -53,7 +53,7 @@ Firebase Core includes FIRApp and FIROptions which provide central configuration # Remember to also update version in `cmake/external/GoogleUtilities.cmake` s.dependency 'GoogleUtilities/Environment', '~> 8.0' s.dependency 'GoogleUtilities/Logger', '~> 8.0' - s.dependency 'FirebaseCoreInternal', '11.5' + s.dependency 'FirebaseCoreInternal', '~> 11.6.0' s.pod_target_xcconfig = { 'GCC_C_LANGUAGE_STANDARD' => 'c99', diff --git a/FirebaseCoreExtension.podspec b/FirebaseCoreExtension.podspec index 59dfad21719..cbabe65f98d 100644 --- a/FirebaseCoreExtension.podspec +++ b/FirebaseCoreExtension.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCoreExtension' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Extended FirebaseCore APIs for Firebase product SDKs' s.description = <<-DESC @@ -34,5 +34,5 @@ Pod::Spec.new do |s| "#{s.module_name}_Privacy" => 'FirebaseCore/Extension/Resources/PrivacyInfo.xcprivacy' } - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' end diff --git a/FirebaseCoreInternal.podspec b/FirebaseCoreInternal.podspec index 30fc10e914a..6cab3696090 100644 --- a/FirebaseCoreInternal.podspec +++ b/FirebaseCoreInternal.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCoreInternal' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'APIs for internal FirebaseCore usage.' s.description = <<-DESC diff --git a/FirebaseCrashlytics.podspec b/FirebaseCrashlytics.podspec index 5426a42bbee..fb0d09d97de 100644 --- a/FirebaseCrashlytics.podspec +++ b/FirebaseCrashlytics.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCrashlytics' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Best and lightest-weight crash reporting for mobile, desktop and tvOS.' s.description = 'Firebase Crashlytics helps you track, prioritize, and fix stability issues that erode app quality.' s.homepage = 'https://firebase.google.com/' @@ -59,7 +59,7 @@ Pod::Spec.new do |s| cp -f ./Crashlytics/CrashlyticsInputFiles.xcfilelist ./CrashlyticsInputFiles.xcfilelist PREPARE_COMMAND_END - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.dependency 'FirebaseInstallations', '~> 11.0' s.dependency 'FirebaseSessions', '~> 11.0' s.dependency 'FirebaseRemoteConfigInterop', '~> 11.0' diff --git a/FirebaseDatabase.podspec b/FirebaseDatabase.podspec index 834211167ba..f6120d4915e 100644 --- a/FirebaseDatabase.podspec +++ b/FirebaseDatabase.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseDatabase' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase Realtime Database' s.description = <<-DESC @@ -47,7 +47,7 @@ Simplify your iOS development, grow your user base, and monetize more effectivel s.macos.frameworks = 'CFNetwork', 'Security', 'SystemConfiguration' s.watchos.frameworks = 'CFNetwork', 'Security', 'WatchKit' s.dependency 'leveldb-library', '~> 1.22' - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.dependency 'FirebaseAppCheckInterop', '~> 11.0' s.dependency 'FirebaseSharedSwift', '~> 11.0' s.dependency 'GoogleUtilities/UserDefaults', '~> 8.0' diff --git a/FirebaseDynamicLinks.podspec b/FirebaseDynamicLinks.podspec index 3d6ce244d8c..dda7be4f589 100644 --- a/FirebaseDynamicLinks.podspec +++ b/FirebaseDynamicLinks.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseDynamicLinks' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase Dynamic Links' s.description = <<-DESC @@ -34,7 +34,7 @@ Firebase Dynamic Links are deep links that enhance user experience and increase } s.frameworks = 'QuartzCore' s.weak_framework = 'WebKit' - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.pod_target_xcconfig = { 'GCC_C_LANGUAGE_STANDARD' => 'c99', diff --git a/FirebaseFirestore.podspec b/FirebaseFirestore.podspec index ff55ec358f1..92f5e3924c8 100644 --- a/FirebaseFirestore.podspec +++ b/FirebaseFirestore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseFirestore' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Google Cloud Firestore' s.description = <<-DESC Google Cloud Firestore is a NoSQL document database built for automatic scaling, high performance, and ease of application development. @@ -35,9 +35,9 @@ Google Cloud Firestore is a NoSQL document database built for automatic scaling, "#{s.module_name}_Privacy" => 'Firestore/Swift/Source/Resources/PrivacyInfo.xcprivacy' } - s.dependency 'FirebaseCore', '11.5' - s.dependency 'FirebaseCoreExtension', '11.5' - s.dependency 'FirebaseFirestoreInternal', '11.5.0' + s.dependency 'FirebaseCore', '~> 11.6.0' + s.dependency 'FirebaseCoreExtension', '~> 11.6.0' + s.dependency 'FirebaseFirestoreInternal', '11.6.0' s.dependency 'FirebaseSharedSwift', '~> 11.0' end diff --git a/FirebaseFirestoreInternal.podspec b/FirebaseFirestoreInternal.podspec index 33a61dbca85..704b099c0a1 100644 --- a/FirebaseFirestoreInternal.podspec +++ b/FirebaseFirestoreInternal.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseFirestoreInternal' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Google Cloud Firestore' s.description = <<-DESC @@ -93,7 +93,7 @@ Google Cloud Firestore is a NoSQL document database built for automatic scaling, } s.dependency 'FirebaseAppCheckInterop', '~> 11.0' - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' abseil_version = '~> 1.20240116.1' s.dependency 'abseil/algorithm', abseil_version diff --git a/FirebaseFunctions.podspec b/FirebaseFunctions.podspec index fb9d748f4cb..e95980c98ee 100644 --- a/FirebaseFunctions.podspec +++ b/FirebaseFunctions.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseFunctions' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Cloud Functions for Firebase' s.description = <<-DESC @@ -35,8 +35,8 @@ Cloud Functions for Firebase. 'FirebaseFunctions/Sources/**/*.swift', ] - s.dependency 'FirebaseCore', '11.5' - s.dependency 'FirebaseCoreExtension', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' + s.dependency 'FirebaseCoreExtension', '~> 11.6.0' s.dependency 'FirebaseAppCheckInterop', '~> 11.0' s.dependency 'FirebaseAuthInterop', '~> 11.0' s.dependency 'FirebaseMessagingInterop', '~> 11.0' diff --git a/FirebaseInAppMessaging.podspec b/FirebaseInAppMessaging.podspec index 9aa37623b15..53fe204fde8 100644 --- a/FirebaseInAppMessaging.podspec +++ b/FirebaseInAppMessaging.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseInAppMessaging' - s.version = '11.5.0-beta' + s.version = '11.6.0-beta' s.summary = 'Firebase In-App Messaging for iOS' s.description = <<-DESC @@ -80,7 +80,7 @@ See more product details at https://firebase.google.com/products/in-app-messagin s.framework = 'UIKit' - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.dependency 'FirebaseInstallations', '~> 11.0' s.dependency 'FirebaseABTesting', '~> 11.0' s.dependency 'GoogleUtilities/Environment', '~> 8.0' diff --git a/FirebaseInstallations.podspec b/FirebaseInstallations.podspec index 377902f1df6..3476e780078 100644 --- a/FirebaseInstallations.podspec +++ b/FirebaseInstallations.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseInstallations' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase Installations' s.description = <<-DESC @@ -45,7 +45,7 @@ Pod::Spec.new do |s| } s.framework = 'Security' - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.dependency 'PromisesObjC', '~> 2.4' s.dependency 'GoogleUtilities/Environment', '~> 8.0' s.dependency 'GoogleUtilities/UserDefaults', '~> 8.0' diff --git a/FirebaseMLModelDownloader.podspec b/FirebaseMLModelDownloader.podspec index 6ca985941e8..879282861a3 100644 --- a/FirebaseMLModelDownloader.podspec +++ b/FirebaseMLModelDownloader.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseMLModelDownloader' - s.version = '11.5.0-beta' + s.version = '11.6.0-beta' s.summary = 'Firebase ML Model Downloader' s.description = <<-DESC @@ -36,8 +36,8 @@ Pod::Spec.new do |s| ] s.framework = 'Foundation' - s.dependency 'FirebaseCore', '11.5' - s.dependency 'FirebaseCoreExtension', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' + s.dependency 'FirebaseCoreExtension', '~> 11.6.0' s.dependency 'FirebaseInstallations', '~> 11.0' s.dependency 'GoogleDataTransport', '~> 10.0' s.dependency 'GoogleUtilities/UserDefaults', '~> 8.0' diff --git a/FirebaseMessaging.podspec b/FirebaseMessaging.podspec index c826363f9e5..95ac97e6631 100644 --- a/FirebaseMessaging.podspec +++ b/FirebaseMessaging.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseMessaging' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase Messaging' s.description = <<-DESC @@ -62,7 +62,7 @@ device, and it is completely free. s.osx.framework = 'SystemConfiguration' s.weak_framework = 'UserNotifications' s.dependency 'FirebaseInstallations', '~> 11.0' - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.dependency 'GoogleUtilities/AppDelegateSwizzler', '~> 8.0' s.dependency 'GoogleUtilities/Reachability', '~> 8.0' s.dependency 'GoogleUtilities/Environment', '~> 8.0' diff --git a/FirebaseMessagingInterop.podspec b/FirebaseMessagingInterop.podspec index 001c05f57c4..b95739b71be 100644 --- a/FirebaseMessagingInterop.podspec +++ b/FirebaseMessagingInterop.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseMessagingInterop' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Interfaces that allow other Firebase SDKs to use Messaging functionality.' s.description = <<-DESC diff --git a/FirebasePerformance.podspec b/FirebasePerformance.podspec index 1215fa057f4..c35aa20a3cc 100644 --- a/FirebasePerformance.podspec +++ b/FirebasePerformance.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebasePerformance' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase Performance' s.description = <<-DESC @@ -59,7 +59,7 @@ Firebase Performance library to measure performance of Mobile and Web Apps. s.ios.framework = 'CoreTelephony' s.framework = 'QuartzCore' s.framework = 'SystemConfiguration' - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.dependency 'FirebaseInstallations', '~> 11.0' s.dependency 'FirebaseRemoteConfig', '~> 11.0' s.dependency 'FirebaseSessions', '~> 11.0' diff --git a/FirebaseRemoteConfig.podspec b/FirebaseRemoteConfig.podspec index d8dfbe3aa84..03eeb4bf80b 100644 --- a/FirebaseRemoteConfig.podspec +++ b/FirebaseRemoteConfig.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseRemoteConfig' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase Remote Config' s.description = <<-DESC @@ -52,7 +52,7 @@ app update. } s.dependency 'FirebaseABTesting', '~> 11.0' s.dependency 'FirebaseSharedSwift', '~> 11.0' - s.dependency 'FirebaseCore', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' s.dependency 'FirebaseInstallations', '~> 11.0' s.dependency 'GoogleUtilities/Environment', '~> 8.0' s.dependency 'GoogleUtilities/NSData+zlib', '~> 8.0' diff --git a/FirebaseRemoteConfigInterop.podspec b/FirebaseRemoteConfigInterop.podspec index 197604250f2..1e8a2078665 100644 --- a/FirebaseRemoteConfigInterop.podspec +++ b/FirebaseRemoteConfigInterop.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseRemoteConfigInterop' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Interfaces that allow other Firebase SDKs to use Remote Config functionality.' s.description = <<-DESC diff --git a/FirebaseSessions.podspec b/FirebaseSessions.podspec index f36099d413d..d54cf449d3c 100644 --- a/FirebaseSessions.podspec +++ b/FirebaseSessions.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseSessions' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase Sessions' s.description = <<-DESC @@ -39,8 +39,8 @@ Pod::Spec.new do |s| base_dir + 'SourcesObjC/**/*.{c,h,m,mm}', ] - s.dependency 'FirebaseCore', '11.5' - s.dependency 'FirebaseCoreExtension', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' + s.dependency 'FirebaseCoreExtension', '~> 11.6.0' s.dependency 'FirebaseInstallations', '~> 11.0' s.dependency 'GoogleDataTransport', '~> 10.0' s.dependency 'GoogleUtilities/Environment', '~> 8.0' diff --git a/FirebaseSharedSwift.podspec b/FirebaseSharedSwift.podspec index ab2345bb104..287e3bef90c 100644 --- a/FirebaseSharedSwift.podspec +++ b/FirebaseSharedSwift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseSharedSwift' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Shared Swift Extensions for Firebase' s.description = <<-DESC diff --git a/FirebaseStorage.podspec b/FirebaseStorage.podspec index bcbe118149b..753a4b558c5 100644 --- a/FirebaseStorage.podspec +++ b/FirebaseStorage.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseStorage' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Firebase Storage' s.description = <<-DESC @@ -39,8 +39,8 @@ Firebase Storage provides robust, secure file uploads and downloads from Firebas s.dependency 'FirebaseAppCheckInterop', '~> 11.0' s.dependency 'FirebaseAuthInterop', '~> 11.0' - s.dependency 'FirebaseCore', '11.5' - s.dependency 'FirebaseCoreExtension', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' + s.dependency 'FirebaseCoreExtension', '~> 11.6.0' s.dependency 'GTMSessionFetcher/Core', '>= 3.4', '< 5.0' s.dependency 'GoogleUtilities/Environment', '~> 8.0' diff --git a/FirebaseVertexAI.podspec b/FirebaseVertexAI.podspec index a6aa6ea5b56..fdfe4d0a3e1 100644 --- a/FirebaseVertexAI.podspec +++ b/FirebaseVertexAI.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseVertexAI' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Vertex AI in Firebase SDK' s.description = <<-DESC @@ -46,8 +46,8 @@ Firebase SDK. s.dependency 'FirebaseAppCheckInterop', '~> 11.4' s.dependency 'FirebaseAuthInterop', '~> 11.4' - s.dependency 'FirebaseCore', '11.5' - s.dependency 'FirebaseCoreExtension', '11.5' + s.dependency 'FirebaseCore', '~> 11.6.0' + s.dependency 'FirebaseCoreExtension', '~> 11.6.0' s.test_spec 'unit' do |unit_tests| unit_tests_dir = 'FirebaseVertexAI/Tests/Unit/' diff --git a/GoogleAppMeasurement.podspec b/GoogleAppMeasurement.podspec index aa4ec6509b7..25b05e666bc 100644 --- a/GoogleAppMeasurement.podspec +++ b/GoogleAppMeasurement.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'GoogleAppMeasurement' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = 'Shared measurement methods for Google libraries. Not intended for direct use.' s.description = <<-DESC @@ -37,7 +37,7 @@ Pod::Spec.new do |s| s.default_subspecs = 'AdIdSupport' s.subspec 'AdIdSupport' do |ss| - ss.dependency 'GoogleAppMeasurement/WithoutAdIdSupport', '11.5.0' + ss.dependency 'GoogleAppMeasurement/WithoutAdIdSupport', '11.6.0' ss.vendored_frameworks = 'Frameworks/GoogleAppMeasurementIdentitySupport.xcframework' end diff --git a/GoogleAppMeasurementOnDeviceConversion.podspec b/GoogleAppMeasurementOnDeviceConversion.podspec index 8250337d28d..5c9f9f8ca2c 100644 --- a/GoogleAppMeasurementOnDeviceConversion.podspec +++ b/GoogleAppMeasurementOnDeviceConversion.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'GoogleAppMeasurementOnDeviceConversion' - s.version = '11.5.0' + s.version = '11.6.0' s.summary = <<-SUMMARY On device conversion measurement plugin for Google App Measurement. Not intended for direct use. diff --git a/Package.swift b/Package.swift index 1fa4deed10a..73151c6c226 100644 --- a/Package.swift +++ b/Package.swift @@ -19,7 +19,7 @@ import class Foundation.ProcessInfo import PackageDescription -let firebaseVersion = "11.5.0" +let firebaseVersion = "11.6.0" let package = Package( name: "Firebase", diff --git a/ReleaseTooling/CarthageJSON/FirebaseABTestingBinary.json b/ReleaseTooling/CarthageJSON/FirebaseABTestingBinary.json index f20a644d7d8..b43f6d31b8d 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseABTestingBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseABTestingBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseABTesting-0d51fde82d49f9e8.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseABTesting-2233510ff87da3b6.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseABTesting-4d0b187af6fd8d67.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseABTesting-0c318b2c019b4484.zip", "4.11.0": "https://dl.google.com/dl/firebase/ios/carthage/4.11.0/ABTesting-d0fdf10c43e985b1.zip", "4.12.0": "https://dl.google.com/dl/firebase/ios/carthage/4.12.0/ABTesting-d0fdf10c43e985b1.zip", "4.9.0": "https://dl.google.com/dl/firebase/ios/carthage/4.9.0/ABTesting-a71d17cadc209af9.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseAdMobBinary.json b/ReleaseTooling/CarthageJSON/FirebaseAdMobBinary.json index 23252863595..892b10e4152 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseAdMobBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseAdMobBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/Google-Mobile-Ads-SDK-4f24527af297e7f1.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/Google-Mobile-Ads-SDK-80ba4cb995505158.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/Google-Mobile-Ads-SDK-3df614a58e6a5fa6.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/Google-Mobile-Ads-SDK-34abc42769a452ec.zip", "4.11.0": "https://dl.google.com/dl/firebase/ios/carthage/4.11.0/AdMob-8a654a42c33bbcc8.zip", "4.12.0": "https://dl.google.com/dl/firebase/ios/carthage/4.12.0/AdMob-63dab3b525b94cd9.zip", "4.9.0": "https://dl.google.com/dl/firebase/ios/carthage/4.9.0/AdMob-134752c6180a2a41.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseAnalyticsBinary.json b/ReleaseTooling/CarthageJSON/FirebaseAnalyticsBinary.json index 7d6c0b1d9c6..6eef13dc1a5 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseAnalyticsBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseAnalyticsBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseAnalytics-a93a6c81da535385.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseAnalytics-fd2c71a90d62b88a.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseAnalytics-525b465eb296d09e.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseAnalytics-7302159af7baa5d6.zip", "4.11.0": "https://dl.google.com/dl/firebase/ios/carthage/4.11.0/Analytics-2468c231ebeb7922.zip", "4.12.0": "https://dl.google.com/dl/firebase/ios/carthage/4.12.0/Analytics-bc8101d420b896c5.zip", "4.9.0": "https://dl.google.com/dl/firebase/ios/carthage/4.9.0/Analytics-d2b6a6b0242db786.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseAnalyticsOnDeviceConversionBinary.json b/ReleaseTooling/CarthageJSON/FirebaseAnalyticsOnDeviceConversionBinary.json index 18dfed2db67..c1494a9cf81 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseAnalyticsOnDeviceConversionBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseAnalyticsOnDeviceConversionBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseAnalyticsOnDeviceConversion-09d94624a2de0ac8.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseAnalyticsOnDeviceConversion-918bc6e0b7a2fd94.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseAnalyticsOnDeviceConversion-1640c514418a23da.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseAnalyticsOnDeviceConversion-8f2f37c75bba22f1.zip", "9.0.0": "https://dl.google.com/dl/firebase/ios/carthage/9.0.0/FirebaseAnalyticsOnDeviceConversion-31aedde70a736b8a.zip", "9.1.0": "https://dl.google.com/dl/firebase/ios/carthage/9.1.0/FirebaseAnalyticsOnDeviceConversion-f13b5a47d1e3978d.zip", "9.2.0": "https://dl.google.com/dl/firebase/ios/carthage/9.2.0/FirebaseAnalyticsOnDeviceConversion-2ebf567c4d97de12.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseAppCheckBinary.json b/ReleaseTooling/CarthageJSON/FirebaseAppCheckBinary.json index 2d7321fbe98..ef662dff5d2 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseAppCheckBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseAppCheckBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseAppCheck-d0c5f46e6a2bf4a3.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseAppCheck-89c39bdcf0bb90fe.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseAppCheck-9b0c4a9489968b07.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseAppCheck-8b9bb98738bf8bcf.zip", "8.0.0": "https://dl.google.com/dl/firebase/ios/carthage/8.0.0/FirebaseAppCheck-9ef1d217cf057203.zip", "8.1.0": "https://dl.google.com/dl/firebase/ios/carthage/8.1.0/FirebaseAppCheck-fc03215d9fe45d3a.zip", "8.10.0": "https://dl.google.com/dl/firebase/ios/carthage/8.10.0/FirebaseAppCheck-6ebe9e9539f06003.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseAppDistributionBinary.json b/ReleaseTooling/CarthageJSON/FirebaseAppDistributionBinary.json index 9aca0a85f2b..6610d08d71d 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseAppDistributionBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseAppDistributionBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseAppDistribution-9b05f4873b275347.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseAppDistribution-6d2eccaccfd3145f.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseAppDistribution-20ac94ca344af731.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseAppDistribution-6d2e83d234fea209.zip", "6.31.0": "https://dl.google.com/dl/firebase/ios/carthage/6.31.0/FirebaseAppDistribution-07f6a2cf7f576a8a.zip", "6.32.0": "https://dl.google.com/dl/firebase/ios/carthage/6.32.0/FirebaseAppDistribution-a9c4f5db794508ca.zip", "6.33.0": "https://dl.google.com/dl/firebase/ios/carthage/6.33.0/FirebaseAppDistribution-448a96d2ade54581.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseAuthBinary.json b/ReleaseTooling/CarthageJSON/FirebaseAuthBinary.json index 36522271aac..4b42255a58b 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseAuthBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseAuthBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseAuth-eade26b5390baf84.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseAuth-93dd2965b3f79b98.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseAuth-5faf6dc3bb16c732.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseAuth-0c8317aa5649f10f.zip", "4.11.0": "https://dl.google.com/dl/firebase/ios/carthage/4.11.0/Auth-0fa76ba0f7956220.zip", "4.12.0": "https://dl.google.com/dl/firebase/ios/carthage/4.12.0/Auth-5ddd2b4351012c7a.zip", "4.9.0": "https://dl.google.com/dl/firebase/ios/carthage/4.9.0/Auth-5e248984d78d7284.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseCrashlyticsBinary.json b/ReleaseTooling/CarthageJSON/FirebaseCrashlyticsBinary.json index 7381237c17b..e1e7795e6e5 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseCrashlyticsBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseCrashlyticsBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseCrashlytics-13851523ad6df088.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseCrashlytics-282a6f3cf3445787.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseCrashlytics-d5c125d6416f6e0a.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseCrashlytics-8b3c9a29b8afd9b3.zip", "6.15.0": "https://dl.google.com/dl/firebase/ios/carthage/6.15.0/FirebaseCrashlytics-1c6d22d5b73c84fd.zip", "6.16.0": "https://dl.google.com/dl/firebase/ios/carthage/6.16.0/FirebaseCrashlytics-938e5fd0e2eab3b3.zip", "6.17.0": "https://dl.google.com/dl/firebase/ios/carthage/6.17.0/FirebaseCrashlytics-fa09f0c8f31ed5d9.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseDatabaseBinary.json b/ReleaseTooling/CarthageJSON/FirebaseDatabaseBinary.json index 99a776b8c34..6e0f6983421 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseDatabaseBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseDatabaseBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseDatabase-06dbb1f7d3c8a3e1.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseDatabase-38634b55050b94fe.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseDatabase-ed125984da534e96.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseDatabase-c31e803cad22c253.zip", "4.11.0": "https://dl.google.com/dl/firebase/ios/carthage/4.11.0/Database-1f7a820452722c7d.zip", "4.12.0": "https://dl.google.com/dl/firebase/ios/carthage/4.12.0/Database-1f7a820452722c7d.zip", "4.9.0": "https://dl.google.com/dl/firebase/ios/carthage/4.9.0/Database-59a12d87456b3e1c.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseDynamicLinksBinary.json b/ReleaseTooling/CarthageJSON/FirebaseDynamicLinksBinary.json index adb21067b99..c4c50f91f6e 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseDynamicLinksBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseDynamicLinksBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseDynamicLinks-e61c61fa80e5ea8a.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseDynamicLinks-95f7e222d8456304.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseDynamicLinks-f3f9d6cc60c8b832.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseDynamicLinks-2d21fc8dc1ab3b10.zip", "4.11.0": "https://dl.google.com/dl/firebase/ios/carthage/4.11.0/DynamicLinks-6a76740211df73f5.zip", "4.12.0": "https://dl.google.com/dl/firebase/ios/carthage/4.12.0/DynamicLinks-6a76740211df73f5.zip", "4.9.0": "https://dl.google.com/dl/firebase/ios/carthage/4.9.0/DynamicLinks-6a76740211df73f5.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseFirestoreBinary.json b/ReleaseTooling/CarthageJSON/FirebaseFirestoreBinary.json index dc4e8e4c326..45a14e7f6e6 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseFirestoreBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseFirestoreBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseFirestore-43af85b854ac842e.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseFirestore-e1283f8cd2e0f3ec.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseFirestore-f5864e67ddbbc9e8.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseFirestore-7cf86f9ac9b3545c.zip", "4.11.0": "https://dl.google.com/dl/firebase/ios/carthage/4.11.0/Firestore-68fc02c229d0cc69.zip", "4.12.0": "https://dl.google.com/dl/firebase/ios/carthage/4.12.0/Firestore-87a804ab561d91db.zip", "4.9.0": "https://dl.google.com/dl/firebase/ios/carthage/4.9.0/Firestore-ecb3eea7bde7e8e8.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseFunctionsBinary.json b/ReleaseTooling/CarthageJSON/FirebaseFunctionsBinary.json index 456117effe1..efd2f26058d 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseFunctionsBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseFunctionsBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseFunctions-307f00117c2efc62.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseFunctions-02693a7583303912.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseFunctions-8fce8623ed1c6b86.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseFunctions-367ecac87d727ede.zip", "4.11.0": "https://dl.google.com/dl/firebase/ios/carthage/4.11.0/Functions-f4c426016dd41e38.zip", "4.12.0": "https://dl.google.com/dl/firebase/ios/carthage/4.12.0/Functions-c6c44427c3034736.zip", "5.0.0": "https://dl.google.com/dl/firebase/ios/carthage/5.0.0/Functions-146f34c401bd459b.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseGoogleSignInBinary.json b/ReleaseTooling/CarthageJSON/FirebaseGoogleSignInBinary.json index 8c45cdd1a76..e8fd8e45d64 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseGoogleSignInBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseGoogleSignInBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/GoogleSignIn-4e8837ef9594b57b.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/GoogleSignIn-8ce1c31ca2236212.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/GoogleSignIn-59eb371d148a2e3a.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/GoogleSignIn-f7dcc2bce87fcb30.zip", "6.0.0": "https://dl.google.com/dl/firebase/ios/carthage/6.0.0/GoogleSignIn-de9c5d5e8eb6d6ea.zip", "6.1.0": "https://dl.google.com/dl/firebase/ios/carthage/6.1.0/GoogleSignIn-8c82f2870573a793.zip", "6.10.0": "https://dl.google.com/dl/firebase/ios/carthage/6.10.0/GoogleSignIn-ff3aef61c4a55b05.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseInAppMessagingBinary.json b/ReleaseTooling/CarthageJSON/FirebaseInAppMessagingBinary.json index b7a994f8a62..13d04a0e6ea 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseInAppMessagingBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseInAppMessagingBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseInAppMessaging-6fae0a778e9d3efa.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseInAppMessaging-3a1a331c86520356.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseInAppMessaging-a8054099dd2918b3.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseInAppMessaging-1264f987e42294c5.zip", "5.10.0": "https://dl.google.com/dl/firebase/ios/carthage/5.10.0/InAppMessaging-a7a3f933362f6e95.zip", "5.11.0": "https://dl.google.com/dl/firebase/ios/carthage/5.11.0/InAppMessaging-fa28ce1b88fbca93.zip", "5.12.0": "https://dl.google.com/dl/firebase/ios/carthage/5.12.0/InAppMessaging-fa28ce1b88fbca93.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseMLModelDownloaderBinary.json b/ReleaseTooling/CarthageJSON/FirebaseMLModelDownloaderBinary.json index 6def9a51b34..93b98c740cd 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseMLModelDownloaderBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseMLModelDownloaderBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseMLModelDownloader-d8649822e63fbf7f.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseMLModelDownloader-517f51af92733a7f.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseMLModelDownloader-069609cbcde7e789.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseMLModelDownloader-c6340805afa15d66.zip", "8.0.0": "https://dl.google.com/dl/firebase/ios/carthage/8.0.0/FirebaseMLModelDownloader-8f972757fb181320.zip", "8.1.0": "https://dl.google.com/dl/firebase/ios/carthage/8.1.0/FirebaseMLModelDownloader-058ad59fa6dc0111.zip", "8.10.0": "https://dl.google.com/dl/firebase/ios/carthage/8.10.0/FirebaseMLModelDownloader-286479a966d2fb37.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseMessagingBinary.json b/ReleaseTooling/CarthageJSON/FirebaseMessagingBinary.json index 9bdf4b5b932..02aa108e989 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseMessagingBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseMessagingBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseMessaging-70e63bb9d9590ded.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseMessaging-8a39834fead3c581.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseMessaging-2d09725e8b98d199.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseMessaging-984ae5d3101abc86.zip", "4.11.0": "https://dl.google.com/dl/firebase/ios/carthage/4.11.0/Messaging-a22ef2b5f2f30f82.zip", "4.12.0": "https://dl.google.com/dl/firebase/ios/carthage/4.12.0/Messaging-94fa4e090c7e9185.zip", "4.9.0": "https://dl.google.com/dl/firebase/ios/carthage/4.9.0/Messaging-2a00a1c64a19d176.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebasePerformanceBinary.json b/ReleaseTooling/CarthageJSON/FirebasePerformanceBinary.json index 666b7238816..ed98e7ed341 100644 --- a/ReleaseTooling/CarthageJSON/FirebasePerformanceBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebasePerformanceBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebasePerformance-aa174ee3102722d9.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebasePerformance-a489ac7a27d9b53d.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebasePerformance-9a6f62e80c2324f4.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebasePerformance-28996619a5fdc4b7.zip", "4.11.0": "https://dl.google.com/dl/firebase/ios/carthage/4.11.0/Performance-d8693eb892bfa05b.zip", "4.12.0": "https://dl.google.com/dl/firebase/ios/carthage/4.12.0/Performance-0a400f9460f7a71d.zip", "4.9.0": "https://dl.google.com/dl/firebase/ios/carthage/4.9.0/Performance-f5b4002ab96523e4.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseRemoteConfigBinary.json b/ReleaseTooling/CarthageJSON/FirebaseRemoteConfigBinary.json index f6e8410b08b..e00f9946e4d 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseRemoteConfigBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseRemoteConfigBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseRemoteConfig-9a298869ce3cc6db.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseRemoteConfig-940ed38696414882.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseRemoteConfig-ec432e976582d0eb.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseRemoteConfig-672acb139b4848ef.zip", "4.11.0": "https://dl.google.com/dl/firebase/ios/carthage/4.11.0/RemoteConfig-7e9635365ccd4a17.zip", "4.12.0": "https://dl.google.com/dl/firebase/ios/carthage/4.12.0/RemoteConfig-e7928fcb6311c439.zip", "4.9.0": "https://dl.google.com/dl/firebase/ios/carthage/4.9.0/RemoteConfig-9ab1ca5f360a1780.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseStorageBinary.json b/ReleaseTooling/CarthageJSON/FirebaseStorageBinary.json index 46f2d604ad5..b5a9246e76e 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseStorageBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseStorageBinary.json @@ -33,6 +33,7 @@ "11.2.0": "https://dl.google.com/dl/firebase/ios/carthage/11.2.0/FirebaseStorage-b9b969b0d1254065.zip", "11.3.0": "https://dl.google.com/dl/firebase/ios/carthage/11.3.0/FirebaseStorage-0435eeaa87324cd4.zip", "11.4.0": "https://dl.google.com/dl/firebase/ios/carthage/11.4.0/FirebaseStorage-0b7a2306152984a2.zip", + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseStorage-a1f0f159f3d7072b.zip", "4.11.0": "https://dl.google.com/dl/firebase/ios/carthage/4.11.0/Storage-6b3e77e1a7fdbc61.zip", "4.12.0": "https://dl.google.com/dl/firebase/ios/carthage/4.12.0/Storage-4721c35d2b90a569.zip", "4.9.0": "https://dl.google.com/dl/firebase/ios/carthage/4.9.0/Storage-821299369b9d0fb2.zip", diff --git a/ReleaseTooling/CarthageJSON/FirebaseVertexAIBinary.json b/ReleaseTooling/CarthageJSON/FirebaseVertexAIBinary.json index 0967ef424bc..6f3fcd57470 100644 --- a/ReleaseTooling/CarthageJSON/FirebaseVertexAIBinary.json +++ b/ReleaseTooling/CarthageJSON/FirebaseVertexAIBinary.json @@ -1 +1,3 @@ -{} +{ + "11.5.0": "https://dl.google.com/dl/firebase/ios/carthage/11.5.0/FirebaseVertexAI-d5d0ffd8010245da.zip" +} diff --git a/ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift b/ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift index 17d32d4c985..bf28d99c158 100755 --- a/ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift +++ b/ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift @@ -21,7 +21,7 @@ import Foundation /// The version and releasing fields of the non-Firebase pods should be reviewed every release. /// The array should be ordered so that any pod's dependencies precede it in the list. public let shared = Manifest( - version: "11.5.0", + version: "11.6.0", pods: [ Pod("FirebaseSharedSwift"), Pod("FirebaseCoreInternal"), @@ -55,6 +55,7 @@ public let shared = Manifest( Pod("FirebaseMLModelDownloader", isBeta: true, zip: true), Pod("FirebaseVertexAI", zip: true), Pod("Firebase", allowWarnings: true, platforms: ["ios", "tvos", "macos"], zip: true), + Pod("FirebaseCombineSwift", releasing: false, zip: false), ] ) @@ -64,6 +65,7 @@ public struct Manifest { public let pods: [Pod] public func versionString(_ pod: Pod) -> String { + let version = pod.podVersion ?? self.version return pod.isBeta ? version + "-beta" : version } } diff --git a/ReleaseTooling/Sources/FirebaseManifest/Pod.swift b/ReleaseTooling/Sources/FirebaseManifest/Pod.swift index ca11ba35b23..0bb5c19a208 100755 --- a/ReleaseTooling/Sources/FirebaseManifest/Pod.swift +++ b/ReleaseTooling/Sources/FirebaseManifest/Pod.swift @@ -28,6 +28,8 @@ public struct Pod { public let allowWarnings: Bool /// Set of platforms (e.g. "ios", "macos", "tvos", or "watchos") to build this pod for. public let platforms: Set + /// Allows overriding the ``Manifest/version`` for this pod; defaults to `nil`. + public let podVersion: String? /// Whether or not the pod is planned for publicly releasing (as some pods are for /// internal/testing use). public let releasing: Bool @@ -47,6 +49,7 @@ public struct Pod { self.isBeta = isBeta self.allowWarnings = allowWarnings self.platforms = platforms + self.podVersion = podVersion self.releasing = releasing self.zip = zip } diff --git a/ReleaseTooling/Sources/ZipBuilder/ZipBuilder.swift b/ReleaseTooling/Sources/ZipBuilder/ZipBuilder.swift index 992ed2e9d89..d19cd4c32e5 100644 --- a/ReleaseTooling/Sources/ZipBuilder/ZipBuilder.swift +++ b/ReleaseTooling/Sources/ZipBuilder/ZipBuilder.swift @@ -361,7 +361,7 @@ struct ZipBuilder { /// - Throws: One of many errors that could have happened during the build phase. func buildAndAssembleFirebaseRelease(templateDir: URL) throws -> ReleaseArtifacts { let manifest = FirebaseManifest.shared - var podsToInstall = manifest.pods.map { + var podsToInstall = manifest.pods.filter { $0.releasing }.map { CocoaPodUtils.VersionedPod(name: $0.name, version: manifest.versionString($0), platforms: $0.platforms) diff --git a/scripts/zip_quickstart_test.sh b/scripts/zip_quickstart_test.sh index 3fb13ebac88..3b531f8e3f9 100755 --- a/scripts/zip_quickstart_test.sh +++ b/scripts/zip_quickstart_test.sh @@ -30,11 +30,23 @@ if [[ ! -z "$LEGACY" ]]; then cd "Legacy${SAMPLE}Quickstart" fi +xcode_version=$(xcodebuild -version | grep Xcode) +xcode_version="${xcode_version/Xcode /}" +xcode_major="${xcode_version/.*/}" + +if [[ "$xcode_major" -lt 15 ]]; then + device_name="iPhone 14" +elif [[ "$xcode_major" -lt 16 ]]; then + device_name="iPhone 15" +else + device_name="iPhone 16" +fi + ( xcodebuild \ -project ${SAMPLE}Example.xcodeproj \ -scheme ${SAMPLE}Example${SWIFT_SUFFIX} \ --destination 'platform=iOS Simulator,name=iPhone 14' "SWIFT_VERSION=5.3" "OTHER_LDFLAGS=\$(OTHER_LDFLAGS) -ObjC" "FRAMEWORK_SEARCH_PATHS= \$(PROJECT_DIR)/Firebase/" HEADER_SEARCH_PATHS='$(PROJECT_DIR)/Firebase' \ +-destination "platform=iOS Simulator,name=$device_name" "SWIFT_VERSION=5.3" "OTHER_LDFLAGS=\$(OTHER_LDFLAGS) -ObjC" "FRAMEWORK_SEARCH_PATHS= \$(PROJECT_DIR)/Firebase/" HEADER_SEARCH_PATHS='$(PROJECT_DIR)/Firebase' \ build \ ) || EXIT_STATUS=$?