ソースを参照

Merge remote-tracking branch 'origin/master' into v9b

Paul Beusterien 4 年 前
コミット
228bf64174

+ 1 - 0
.github/workflows/prerelease.yml

@@ -481,6 +481,7 @@ jobs:
       bot_token_secret: ${{ secrets.GHASecretsGPGPassphrase1 }}
       testing_repo_dir: "/tmp/test/"
       testing_repo: "firebase-ios-sdk"
+      LEGACY: true
     runs-on: macos-11
     steps:
     - uses: actions/checkout@v2

+ 10 - 0
.github/workflows/zip.yml

@@ -514,20 +514,30 @@ jobs:
         mkdir -p "${HOME}"/ios_frameworks/
         find "${GITHUB_WORKSPACE}/${FRAMEWORK_DIR}" -name "Firebase*latest.zip" -exec unzip -d "${HOME}"/ios_frameworks/ {} +
     - name: Setup quickstart
+      env:
+        LEGACY: true
       run: SAMPLE="$SDK" TARGET="${SDK}Example" scripts/setup_quickstart_framework.sh \
                                                "${HOME}"/ios_frameworks/Firebase/FirebaseStorage/* \
                                                "${HOME}"/ios_frameworks/Firebase/FirebaseAuth/* \
                                                "${HOME}"/ios_frameworks/Firebase/FirebaseAnalytics/*
     - name: Setup swift quickstart
+      env:
+        LEGACY: true
       run: SAMPLE="$SDK" TARGET="${SDK}ExampleSwift" scripts/setup_quickstart_framework.sh
     - name: Install Secret GoogleService-Info.plist
       run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/qs-storage.plist.gpg \
         quickstart-ios/storage/GoogleService-Info.plist "$plist_secret"
     - name: Test Quickstart
+      env:
+        LEGACY: true
       run: ([ -z $plist_secret ] || scripts/third_party/travis/retry.sh scripts/test_quickstart_framework.sh "${SDK}")
     - name: Test Swift Quickstart
+      env:
+        LEGACY: true
       run: ([ -z $plist_secret ] || scripts/third_party/travis/retry.sh scripts/test_quickstart_framework.sh "${SDK}" swift)
     - name: Remove data before upload
+      env:
+        LEGACY: true
       if: ${{ failure() }}
       run: scripts/remove_data.sh storage
     - uses: actions/upload-artifact@v2

+ 5 - 0
Firestore/CHANGELOG.md

@@ -3,6 +3,11 @@
   assertion about ordering documents by missing fields (#9258).
 - [changed] Add more details to the assertion failure in Query::Comparator() to
   help with future debugging (#9258).
+- [fixed] **Breaking change:** Fixed an issue where returning `nil` from the
+  update closure when running a transaction caused a crash in Swift by removing
+  the auto-generated `async throw`ing method from the `FirebaseFirestore`
+  module. In order to use the `async throw`ing transaction method, add the
+  `FirebaseFirestoreSwift` module dependency to your build target (#9426).
 
 # v8.14.0
 - [fixed] Fixed compiler warnings in `local_serializer.cc` about "implicit

+ 2 - 1
Firestore/Source/Public/FirebaseFirestore/FIRFirestore.h

@@ -143,7 +143,8 @@ NS_SWIFT_NAME(Firestore)
  *     block will run even if the client is offline, unless the process is killed.
  */
 - (void)runTransactionWithBlock:(id _Nullable (^)(FIRTransaction *, NSError **))updateBlock
-                     completion:(void (^)(id _Nullable result, NSError *_Nullable error))completion;
+                     completion:(void (^)(id _Nullable result, NSError *_Nullable error))completion
+    __attribute__((swift_async(none)));  // Disable async import due to #9426.
 
 /**
  * Creates a write batch, used for performing multiple writes as a single

+ 45 - 0
Firestore/Swift/Source/AsyncAwait/Firestore+AsyncAwait.swift

@@ -53,5 +53,50 @@ import Foundation
         }
       }
     }
+
+    /// Executes the given updateBlock and then attempts to commit the changes applied within an atomic
+    /// transaction.
+    ///
+    /// The maximum number of writes allowed in a single transaction is 500, but note that each usage of
+    /// `FieldValue.serverTimestamp()`, `FieldValue.arrayUnion()`, `FieldValue.arrayRemove()`, or
+    /// `FieldValue.increment()` inside a transaction counts as an additional write.
+    ///
+    /// In the `updateBlock`, a set of reads and writes can be performed atomically using the
+    /// `Transaction` object passed to the block. After the `updateBlock` is run, Firestore will attempt
+    /// to apply the changes to the server. If any of the data read has been modified outside of this
+    /// transaction since being read, then the transaction will be retried by executing the `updateBlock`
+    /// again. If the transaction still fails after 5 retries, then the transaction will fail.
+    ///
+    /// Since the `updateBlock` may be executed multiple times, it should avoiding doing anything that
+    /// would cause side effects.
+    ///
+    /// Any value maybe be returned from the `updateBlock`. If the transaction is successfully committed,
+    /// then the completion block will be passed that value. The `updateBlock` also has an `NSError` out
+    /// parameter. If this is set, then the transaction will not attempt to commit, and the given error
+    /// will be returned.
+    ///
+    /// The `Transaction` object passed to the `updateBlock` contains methods for accessing documents
+    /// and collections. Unlike other firestore access, data accessed with the transaction will not
+    /// reflect local changes that have not been committed. For this reason, it is required that all
+    /// reads are performed before any writes. Transactions must be performed while online. Otherwise,
+    /// reads will fail, the final commit will fail, and this function will return an error.
+    ///
+    /// - Parameter updateBlock The block to execute within the transaction context.
+    /// - Throws Throws an error if the transaction could not be committed, or if an error was explicitly specified in the `updateBlock` parameter.
+    /// - Returns Returns the value returned in the `updateBlock` parameter if no errors occurred.
+    func runTransaction(_ updateBlock: @escaping (Transaction, NSErrorPointer)
+      -> Any?) async throws -> Any? {
+      // This needs to be wrapped in order to express a nullable return value upon success.
+      // See https://github.com/firebase/firebase-ios-sdk/issues/9426 for more details.
+      return try await withCheckedThrowingContinuation { continuation in
+        self.runTransaction(updateBlock) { anyValue, error in
+          if let err = error {
+            continuation.resume(throwing: err)
+          } else {
+            continuation.resume(returning: anyValue)
+          }
+        }
+      }
+    }
   }
 #endif

+ 8 - 0
Firestore/Swift/Tests/Integration/AsyncAwaitIntegrationTests.swift

@@ -65,5 +65,13 @@ let emptyBundle = """
         .loadBundle(InputStream(data: bundle.data(using: String.Encoding.utf8)!))
       XCTAssertEqual(LoadBundleTaskState.success, bundleProgress.state)
     }
+
+    func testRunTransactionDoesNotCrashOnNilSuccess() async throws {
+      let value = try await db.runTransaction { transact, error in
+        nil // should not crash
+      }
+
+      XCTAssertNil(value, "value should be nil on success")
+    }
   }
 #endif

+ 5 - 4
README.md

@@ -30,8 +30,7 @@
 
 # Firebase Apple Open Source Development
 
-This repository contains all Apple platform Firebase SDK source except FirebaseAnalytics
-and FirebaseML.
+This repository contains all Apple platform Firebase SDK source except FirebaseAnalytics.
 
 Firebase is an app development platform with tools to help you build, grow and
 monetize your app. More information about Firebase can be found on the
@@ -39,7 +38,9 @@ monetize your app. More information about Firebase can be found on the
 
 ## Installation
 
-See the subsections below for details about the different installation methods.
+See the subsections below for details about the different installation methods. Where
+available, it's recommended to install any libraries with a `Swift` suffix to get the
+best experience when writing your app in Swift.
 1. [Standard pod install](#standard-pod-install)
 1. [Swift Package Manager](#swift-package-manager)
 1. [Installing from the GitHub repo](#installing-from-github)
@@ -243,7 +244,7 @@ physical device.
 
 ## Building with Firebase on Apple platforms
 
-Firebase 8.9.0 introduces official beta support for macOS, Catalyst, and tvOS. watchOS continues
+Firebase 8.9.0 introduced official beta support for macOS, Catalyst, and tvOS. watchOS continues
 to be community supported. Thanks to community contributions for many of the multi-platform PRs.
 
 At this time, most of Firebase's products are available across Apple platforms. There are still

+ 0 - 3
scripts/setup_quickstart_framework.sh

@@ -21,9 +21,6 @@ fi
 QS_SCRIPTS="${REPO}"/quickstart-ios/scripts
 cd quickstart-ios/"${SAMPLE}"
 
-chmod +x "${QS_SCRIPTS}"/info_script.rb
-ruby "${QS_SCRIPTS}"/info_script.rb "${SAMPLE}" "${LEGACY:-}"
-
 if [[ ! -z "$LEGACY" ]]; then
   cd "Legacy${SAMPLE}Quickstart"
 fi