فهرست منبع

Merge branch 'master' into appcheck-auth-bug-bash

Rosalyn Tan 3 سال پیش
والد
کامیت
956cb84718
33فایلهای تغییر یافته به همراه845 افزوده شده و 183 حذف شده
  1. 1 1
      Crashlytics/Crashlytics/Components/FIRCLSCrashedMarkerFile.c
  2. 1 1
      Crashlytics/Crashlytics/Components/FIRCLSHost.m
  3. 1 1
      FirebaseAnalytics.podspec
  4. 3 2
      FirebaseAuth/CHANGELOG.md
  5. 30 0
      FirebaseAuth/Sources/Auth/FIRAuth.m
  6. 1 1
      FirebaseAuth/Sources/Auth/FIRAuthGlobalWorkQueue.m
  7. 31 0
      FirebaseAuth/Sources/Backend/FIRAuthBackend.h
  8. 25 0
      FirebaseAuth/Sources/Backend/FIRAuthBackend.m
  9. 63 0
      FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenRequest.h
  10. 103 0
      FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenRequest.m
  11. 27 0
      FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenResponse.h
  12. 29 0
      FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenResponse.m
  13. 8 0
      FirebaseAuth/Sources/Public/FirebaseAuth/FIRAuth.h
  14. 43 1
      FirebaseAuth/Tests/Sample/Sample/MainViewController+OAuth.m
  15. 1 1
      FirebaseAuth/Tests/Unit/FIRAuthBackendRPCImplementationTests.m
  16. 111 0
      FirebaseAuth/Tests/Unit/FIRAuthTests.m
  17. 124 0
      FirebaseAuth/Tests/Unit/FIRRevokeTokenRequestTests.m
  18. 117 0
      FirebaseAuth/Tests/Unit/FIRRevokeTokenResponseTests.m
  19. 4 0
      FirebaseCore/CHANGELOG.md
  20. 1 0
      FirebaseDatabaseSwift/Sources/Codable/DataSnapshot+ReadDecodable.swift
  21. 1 0
      FirebaseDatabaseSwift/Sources/Codable/DatabaseReference+WriteEncodable.swift
  22. 4 4
      FirebaseMessaging/Sources/FIRMessagingUtilities.m
  23. 0 2
      FirebaseTestingSupport/Firestore/Sources/FIRQueryFake.mm
  24. 5 0
      Firestore/CHANGELOG.md
  25. 0 6
      Firestore/core/include/firebase/firestore/timestamp.h
  26. 1 1
      GoogleAppMeasurement.podspec
  27. 95 152
      Package.swift
  28. 2 2
      cmake/compiler_setup.cmake
  29. 2 2
      cmake/external/abseil-cpp.cmake
  30. 2 2
      cmake/external/grpc.cmake
  31. 1 1
      scripts/build.sh
  32. 3 3
      scripts/setup_spm_tests.sh
  33. 5 0
      scripts/style.sh

+ 1 - 1
Crashlytics/Crashlytics/Components/FIRCLSCrashedMarkerFile.c

@@ -18,7 +18,7 @@
 
 const char *FIRCLSCrashedMarkerFileName = "previously-crashed";
 
-void FIRCLSCreateCrashedMarkerFile() {
+void FIRCLSCreateCrashedMarkerFile(void) {
   FIRCLSFile file;
 
   if (!FIRCLSFileInitWithPath(&file, _firclsContext.readonly->previouslyCrashedFileFullPath, false)) {

+ 1 - 1
Crashlytics/Crashlytics/Components/FIRCLSHost.m

@@ -106,7 +106,7 @@ vm_size_t FIRCLSHostGetPageSize(void) {
 
 // This comes from the Apple documentation here:
 // https://developer.apple.com/documentation/apple_silicon/about_the_rosetta_translation_environment
-bool FIRCLSHostIsRosettaTranslated() {
+bool FIRCLSHostIsRosettaTranslated(void) {
 #if TARGET_OS_MAC
   int result = 0;
   size_t size = sizeof(result);

+ 1 - 1
FirebaseAnalytics.podspec

@@ -13,7 +13,7 @@ Pod::Spec.new do |s|
     s.authors          = 'Google, Inc.'
 
     s.source           = {
-        :http => 'https://dl.google.com/firebase/ios/analytics/c549faaa5cd321b5/FirebaseAnalytics-10.6.0.tar.gz'
+        :http => 'https://dl.google.com/firebase/ios/analytics/5f0d532a0eb9e9ca/FirebaseAnalytics-10.8.0.tar.gz'
     }
 
     s.cocoapods_version = '>= 1.10.0'

+ 3 - 2
FirebaseAuth/CHANGELOG.md

@@ -1,5 +1,6 @@
-#Unrealeased
-- [feature] Added Firebase App Check support to Firebase Auth.
+# 10.8.0
+- [added] Added Firebase App Check support to Firebase Auth. (#11056)
+- [added] Added sign in with Apple token revocation support. (#9906)
 
 # 10.7.0
 - [added] Added an API for developers to pass the fullName from the Sign in with Apple credential to Firebase. (#10068)

+ 30 - 0
FirebaseAuth/Sources/Auth/FIRAuth.m

@@ -47,6 +47,8 @@
 #import "FirebaseAuth/Sources/Backend/RPC/FIRGetOOBConfirmationCodeResponse.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRResetPasswordRequest.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRResetPasswordResponse.h"
+#import "FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenRequest.h"
+#import "FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenResponse.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRSendVerificationCodeRequest.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRSendVerificationCodeResponse.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRSetAccountInfoRequest.h"
@@ -1544,6 +1546,34 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
   });
 }
 
+- (void)revokeTokenWithAuthorizationCode:(NSString *)authorizationCode
+                              completion:(nullable void (^)(NSError *_Nullable error))completion {
+  [self.currentUser
+      getIDTokenWithCompletion:^(NSString *_Nullable idToken, NSError *_Nullable error) {
+        if (completion) {
+          if (error) {
+            completion(error);
+            return;
+          }
+        }
+        FIRRevokeTokenRequest *request =
+            [[FIRRevokeTokenRequest alloc] initWithToken:authorizationCode
+                                                 idToken:idToken
+                                    requestConfiguration:self->_requestConfiguration];
+        [FIRAuthBackend
+            revokeToken:request
+               callback:^(FIRRevokeTokenResponse *_Nullable response, NSError *_Nullable error) {
+                 if (completion) {
+                   if (error) {
+                     completion(error);
+                   } else {
+                     completion(nil);
+                   }
+                 }
+               }];
+      }];
+}
+
 #if TARGET_OS_IOS
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-property-ivar"

+ 1 - 1
FirebaseAuth/Sources/Auth/FIRAuthGlobalWorkQueue.m

@@ -18,7 +18,7 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
-dispatch_queue_t FIRAuthGlobalWorkQueue() {
+dispatch_queue_t FIRAuthGlobalWorkQueue(void) {
   static dispatch_once_t once;
   static dispatch_queue_t queue;
   dispatch_once(&once, ^{

+ 31 - 0
FirebaseAuth/Sources/Backend/FIRAuthBackend.h

@@ -54,6 +54,8 @@
 @class FIRSignInWithGameCenterResponse;
 @class FIRSignUpNewUserRequest;
 @class FIRSignUpNewUserResponse;
+@class FIRRevokeTokenRequest;
+@class FIRRevokeTokenResponse;
 
 @protocol FIRAuthBackendImplementation;
 @protocol FIRAuthBackendRPCIssuer;
@@ -220,6 +222,15 @@ typedef void (^FIRVerifyPhoneNumberResponseCallback)(
 typedef void (^FIRVerifyClientResponseCallback)(FIRVerifyClientResponse *_Nullable response,
                                                 NSError *_Nullable error);
 
+/** @typedef FIRRevokeTokenResponseCallback
+    @brief The type of block used to return the result of a call to the revokeToken endpoint.
+    @param response The received response, if any.
+    @param error The error which occurred, if any.
+    @remarks One of response or error will be non-nil.
+ */
+typedef void (^FIRRevokeTokenResponseCallback)(FIRRevokeTokenResponse *_Nullable response,
+                                               NSError *_Nullable error);
+
 /** @typedef FIRSignInWithGameCenterResponseCallback
     @brief The type of block used to return the result of a call to the SignInWithGameCenter
    endpoint.
@@ -414,8 +425,18 @@ typedef void (^FIRSignInWithGameCenterResponseCallback)(
  */
 + (void)verifyClient:(FIRVerifyClientRequest *)request
             callback:(FIRVerifyClientResponseCallback)callback;
+
 #endif
 
+/** @fn revokeToken:callback:
+    @brief Calls the revokeToken endpoint, which is responsible for revoking the given token
+        provided in the request parameters.
+    @param request The request parameters.
+    @param callback The callback.
+ */
++ (void)revokeToken:(FIRRevokeTokenRequest *)request
+           callback:(FIRRevokeTokenResponseCallback)callback;
+
 @end
 
 /** @protocol FIRAuthBackendRPCIssuer
@@ -578,8 +599,18 @@ typedef void (^FIRSignInWithGameCenterResponseCallback)(
  */
 - (void)verifyClient:(FIRVerifyClientRequest *)request
             callback:(FIRVerifyClientResponseCallback)callback;
+
 #endif
 
+/** @fn revokeToken:callback:
+    @brief Calls the revokeToken endpoint, which is responsible for revoking the given token
+        provided in the request parameters.
+    @param request The request parameters.
+    @param callback The callback.
+ */
+- (void)revokeToken:(FIRRevokeTokenRequest *)request
+           callback:(FIRRevokeTokenResponseCallback)callback;
+
 /** @fn SignInWithGameCenter:callback:
     @brief Calls the SignInWithGameCenter endpoint, which is responsible for authenticating a user
       who has Game Center credentials.

+ 25 - 0
FirebaseAuth/Sources/Backend/FIRAuthBackend.m

@@ -44,6 +44,8 @@
 #import "FirebaseAuth/Sources/Backend/RPC/FIRGetProjectConfigResponse.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRResetPasswordRequest.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRResetPasswordResponse.h"
+#import "FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenRequest.h"
+#import "FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenResponse.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRSecureTokenRequest.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRSecureTokenResponse.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRSendVerificationCodeRequest.h"
@@ -606,8 +608,14 @@ static id<FIRAuthBackendImplementation> gBackendImplementation;
 + (void)verifyClient:(id)request callback:(FIRVerifyClientResponseCallback)callback {
   [[self implementation] verifyClient:request callback:callback];
 }
+
 #endif
 
++ (void)revokeToken:(FIRRevokeTokenRequest *)request
+           callback:(FIRRevokeTokenResponseCallback)callback {
+  [[self implementation] revokeToken:request callback:callback];
+}
+
 + (void)resetPassword:(FIRResetPasswordRequest *)request
              callback:(FIRResetPasswordCallback)callback {
   [[self implementation] resetPassword:request callback:callback];
@@ -989,8 +997,25 @@ static id<FIRAuthBackendImplementation> gBackendImplementation;
                  callback(response, nil);
                }];
 }
+
 #endif
 
+- (void)revokeToken:(FIRRevokeTokenRequest *)request
+           callback:(FIRRevokeTokenResponseCallback)callback {
+  FIRRevokeTokenResponse *response = [[FIRRevokeTokenResponse alloc] init];
+  [self
+      postWithRequest:request
+             response:response
+             callback:^(NSError *error) {
+               if (error) {
+                 callback(nil, [FIRAuthErrorUtils
+                                   invalidCredentialErrorWithMessage:[error localizedDescription]]);
+                 return;
+               }
+               callback(response, nil);
+             }];
+}
+
 - (void)resetPassword:(FIRResetPasswordRequest *)request
              callback:(FIRResetPasswordCallback)callback {
   FIRResetPasswordResponse *response = [[FIRResetPasswordResponse alloc] init];

+ 63 - 0
FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenRequest.h

@@ -0,0 +1,63 @@
+/*
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FirebaseAuth/Sources/Backend/FIRAuthRPCRequest.h"
+#import "FirebaseAuth/Sources/Backend/FIRIdentityToolkitRequest.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FIRRevokeTokenRequest : FIRIdentityToolkitRequest <FIRAuthRPCRequest>
+
+/** @property providerID
+    @brief The provider that issued the token to revoke.
+ */
+@property(nonatomic, copy, nullable) NSString *providerID;
+
+/** @property tokenType
+    @brief The type of the token to revoke.
+ */
+@property(nonatomic) NSInteger tokenType;
+
+/** @property token
+    @brief The token to be revoked.
+ */
+@property(nonatomic, copy, nullable) NSString *token;
+
+/** @property idToken
+    @brief The ID Token associated with this credential.
+ */
+@property(nonatomic, copy, nullable) NSString *idToken;
+
+/** @fn initWithEndpoint:requestConfiguration:
+    @brief Please use initWithToken:requestConfiguration: instead.
+ */
+- (nullable instancetype)initWithEndpoint:(NSString *)endpoint
+                     requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration
+    NS_UNAVAILABLE;
+
+/** @fn initWithAppToken:isSandbox:requestConfiguration:
+    @brief Designated initializer.
+    @param token The token to be revoked.
+    @param idToken The id token associated with the current user.
+    @param requestConfiguration An object containing configurations to be added to the request.
+ */
+- (nullable instancetype)initWithToken:(NSString *)token
+                               idToken:(NSString *)idToken
+                  requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 103 - 0
FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenRequest.m

@@ -0,0 +1,103 @@
+/*
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenRequest.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/** @var kRevokeTokenEndpoint
+    @brief The endpoint for the revokeToken request.
+ */
+static NSString *const kRevokeTokenEndpoint = @"accounts:revokeToken";
+
+/** @var kProviderIDKey
+    @brief The key for the provider that issued the token to revoke.
+ */
+static NSString *const kProviderIDKey = @"providerId";
+
+/** @var kTokenTypeKey
+    @brief The key for the type of the token to revoke.
+ */
+static NSString *const kTokenTypeKey = @"tokenType";
+
+/** @var kTokenKey
+    @brief The key for the token to be revoked.
+ */
+static NSString *const kTokenKey = @"token";
+
+/** @var kIDTokenKey
+    @brief The key for the ID Token associated with this credential.
+ */
+static NSString *const kIDTokenKey = @"idToken";
+
+typedef NS_ENUM(NSInteger, FIRTokenType) {
+  /** Indicates that the token type is unspecified.
+   */
+  FIRTokenTypeUnspecified = 0,
+
+  /** Indicates that the token type is refresh token.
+   */
+  FIRTokenTypeRefreshToken = 1,
+
+  /** Indicates that the token type is access token.
+   */
+  FIRTokenTypeAccessToken = 2,
+
+  /** Indicates that the token type is authorization code.
+   */
+  FIRTokenTypeAuthorizationCode = 3,
+};
+
+@implementation FIRRevokeTokenRequest
+
+- (nullable instancetype)initWithToken:(NSString *)token
+                               idToken:(NSString *)idToken
+                  requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration {
+  self = [super initWithEndpoint:kRevokeTokenEndpoint
+            requestConfiguration:requestConfiguration
+             useIdentityPlatform:YES
+                      useStaging:NO];
+  if (self) {
+    // Apple and authorization code are the only provider and token type we support for now.
+    // Generalize this initializer to accept other providers and token types once supported.
+    _providerID = @"apple.com";
+    _tokenType = FIRTokenTypeAuthorizationCode;
+    _token = token;
+    _idToken = idToken;
+  }
+  return self;
+}
+
+- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *__autoreleasing _Nullable *)error {
+  NSMutableDictionary *postBody = [NSMutableDictionary dictionary];
+  if (_providerID) {
+    postBody[kProviderIDKey] = _providerID;
+  }
+  if (_tokenType) {
+    postBody[kTokenTypeKey] = [NSNumber numberWithInteger:_tokenType].stringValue;
+  }
+  if (_token) {
+    postBody[kTokenKey] = _token;
+  }
+  if (_idToken) {
+    postBody[kIDTokenKey] = _idToken;
+  }
+  return [postBody copy];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 27 - 0
FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenResponse.h

@@ -0,0 +1,27 @@
+/*
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+#import "FirebaseAuth/Sources/Backend/FIRAuthRPCResponse.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FIRRevokeTokenResponse : NSObject <FIRAuthRPCResponse>
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 29 - 0
FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenResponse.m

@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenResponse.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation FIRRevokeTokenResponse
+
+- (BOOL)setWithDictionary:(NSDictionary *)dictionary error:(NSError *_Nullable *_Nullable)error {
+  return YES;
+}
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 8 - 0
FirebaseAuth/Sources/Public/FirebaseAuth/FIRAuth.h

@@ -850,6 +850,14 @@ NS_SWIFT_NAME(Auth)
  */
 - (BOOL)canHandleNotification:(NSDictionary *)userInfo API_UNAVAILABLE(macos, tvos, watchos);
 
+/** @fn revokeTokenWithAuthorizationCode:Completion
+    @brief Revoke the users token with authorization code.
+    @param completion (Optional) the block invoked when the request to revoke the token is
+        complete, or fails. Invoked asynchronously on the main thread in the future.
+ */
+- (void)revokeTokenWithAuthorizationCode:(NSString *)authorizationCode
+                              completion:(nullable void (^)(NSError *_Nullable error))completion;
+
 #pragma mark - User sharing
 
 /** @fn useUserAccessGroup:error:

+ 43 - 1
FirebaseAuth/Tests/Sample/Sample/MainViewController+OAuth.m

@@ -49,6 +49,8 @@ NS_ASSUME_NONNULL_BEGIN
                                        action:^{ [weakSelf unlinkFromProvider:@"apple.com" completion:nil]; }],
     [StaticContentTableViewCell cellWithTitle:@"Reauthenticate with Apple"
                                        action:^{ [weakSelf reauthenticateWithApple]; }],
+    [StaticContentTableViewCell cellWithTitle:@"Revoke Apple Token and Delete User"
+                                       action:^{ [weakSelf revokeAppleTokenAndDeleteUser]; }],
     [StaticContentTableViewCell cellWithTitle:@"Sign in with Twitter"
                                        action:^{ [weakSelf signInTwitterHeadfulLite]; }],
     [StaticContentTableViewCell cellWithTitle:@"Sign in with GitHub"
@@ -407,6 +409,30 @@ NS_ASSUME_NONNULL_BEGIN
   }
 }
 
+- (void)revokeAppleTokenAndDeleteUser {
+    FIRUser *user = [FIRAuth auth].currentUser;
+
+    // Optionally revoke Apple token before account deletion
+    BOOL isAppleProviderLinked = false;
+    for (id<FIRUserInfo> provider in user.providerData) {
+        if ([[provider providerID]  isEqual: @"apple.com"]) {
+            isAppleProviderLinked = true;
+        }
+    }
+    if (isAppleProviderLinked) {
+        if (@available(iOS 13, *)) {
+          ASAuthorizationAppleIDRequest* request = [self appleIDRequestWithState:@"revokeAppleTokenAndDeleteUser"];
+          ASAuthorizationController* controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
+          controller.delegate = self;
+          controller.presentationContextProvider = self;
+          [controller performRequests];
+
+        } else {
+        // Usual user deletion
+    }
+      }
+}
+
 - (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)) {
   ASAuthorizationAppleIDCredential* appleIDCredential = authorization.credential;
   NSString *IDToken = [NSString stringWithUTF8String:[appleIDCredential.identityToken bytes]];
@@ -439,7 +465,23 @@ NS_ASSUME_NONNULL_BEGIN
         NSLog(@"%@", error.description);
       }
     }];
-  }
+  } else if ([appleIDCredential.state isEqualToString:@"revokeAppleTokenAndDeleteUser"]) {
+      NSString *code = [[NSString alloc] initWithData:appleIDCredential.authorizationCode encoding:NSUTF8StringEncoding];
+      FIRUser *user = FIRAuth.auth.currentUser;
+      [FIRAuth.auth revokeTokenWithAuthorizationCode:code completion:^(NSError * _Nullable error) {
+          if (!error) {
+              // Token revocation succeeded then delete user again.
+              [user deleteWithCompletion:^(NSError *_Nullable error) {
+                if (error) {
+                  [self logFailure:@"delete account failed" error:error];
+                }
+                [self showTypicalUIForUserUpdateResultsWithTitle:@"Delete User" error:error];
+              }];
+          } else {
+            NSLog(@"%@", error.description);
+          }
+      }];
+    }
 }
 
 - (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)) {

+ 1 - 1
FirebaseAuth/Tests/Unit/FIRAuthBackendRPCImplementationTests.m

@@ -465,7 +465,7 @@ static NSString *const kTestValue = @"TestValue";
 /** @fn testRequest_IncludesAppCheckHeader
     @brief This test checks the behavior of @c postWithRequest:response:callback:
         to verify that a appCheck token is attached as a header to an
-        outgoing request .
+        outgoing request.
  */
 - (void)testRequest_IncludesAppCheckHeader {
   // Given

+ 111 - 0
FirebaseAuth/Tests/Unit/FIRAuthTests.m

@@ -45,6 +45,8 @@
 #import "FirebaseAuth/Sources/Backend/RPC/FIRGetOOBConfirmationCodeResponse.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRResetPasswordRequest.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRResetPasswordResponse.h"
+#import "FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenRequest.h"
+#import "FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenResponse.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRSecureTokenRequest.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRSecureTokenResponse.h"
 #import "FirebaseAuth/Sources/Backend/RPC/FIRSetAccountInfoRequest.h"
@@ -2773,4 +2775,113 @@ static const NSTimeInterval kWaitInterval = .5;
                           DISPATCH_TIME_FOREVER /*DISPATCH_TIME_NOW + 10 * NSEC_PER_SEC*/);
 }
 
+/** @fn testRevokeTokenSuccess
+    @brief Tests the flow of a successful @c revokeToken:completion.
+ */
+- (void)testRevokeTokenSuccess {
+  OCMExpect([_mockBackend verifyPassword:[OCMArg any] callback:[OCMArg any]])
+      .andCallBlock2(^(FIRVerifyPasswordRequest *_Nullable request,
+                       FIRVerifyPasswordResponseCallback callback) {
+        XCTAssertEqualObjects(request.APIKey, kAPIKey);
+        XCTAssertEqualObjects(request.email, kEmail);
+        XCTAssertEqualObjects(request.password, kFakePassword);
+        XCTAssertTrue(request.returnSecureToken);
+        dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
+          id mockVerifyPasswordResponse = OCMClassMock([FIRVerifyPasswordResponse class]);
+          [self stubTokensWithMockResponse:mockVerifyPasswordResponse];
+          callback(mockVerifyPasswordResponse, nil);
+        });
+      });
+  [self expectGetAccountInfo];
+  XCTestExpectation *signInExpectation = [self expectationWithDescription:@"signIn"];
+  [[FIRAuth auth] signOut:NULL];
+  [[FIRAuth auth] signInWithEmail:kEmail
+                         password:kFakePassword
+                       completion:^(FIRAuthDataResult *_Nullable result, NSError *_Nullable error) {
+                         [self assertUser:result.user];
+                         XCTAssertNil(error);
+                         [signInExpectation fulfill];
+                       }];
+  [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
+  [self assertUser:[FIRAuth auth].currentUser];
+  id mockSecureTokenResponse = OCMClassMock([FIRSecureTokenResponse class]);
+  OCMStub([mockSecureTokenResponse accessToken]).andReturn(@"IDToken");
+  OCMExpect([self->_mockBackend secureToken:[OCMArg any] callback:[OCMArg any]])
+      .andCallBlock2(
+          ^(FIRSecureTokenRequest *_Nullable request, FIRSecureTokenResponseCallback callback) {
+            dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
+              callback(mockSecureTokenResponse, nil);
+            });
+          });
+  OCMExpect([_mockBackend revokeToken:[OCMArg any] callback:[OCMArg any]])
+      .andCallBlock2(
+          ^(FIRRevokeTokenRequest *_Nullable request, FIRRevokeTokenResponseCallback callback) {
+            dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
+              id mockRevokeTokenResponse = OCMClassMock([FIRRevokeTokenResponse class]);
+              callback(mockRevokeTokenResponse, nil);
+            });
+          });
+  XCTestExpectation *revokeExpectation = [self expectationWithDescription:@"callback"];
+  NSString *code = @"code";
+  [[FIRAuth auth] revokeTokenWithAuthorizationCode:code
+                                        completion:^(NSError *_Nullable error) {
+                                          XCTAssertNil(error);
+                                          [revokeExpectation fulfill];
+                                        }];
+  [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
+}
+
+/** @fn testRevokeTokenMissingCallback
+    @brief Tests the flow of  @c revokeToken:completion with a nil callback.
+ */
+- (void)testRevokeTokenMissingCallback {
+  OCMExpect([_mockBackend verifyPassword:[OCMArg any] callback:[OCMArg any]])
+      .andCallBlock2(^(FIRVerifyPasswordRequest *_Nullable request,
+                       FIRVerifyPasswordResponseCallback callback) {
+        XCTAssertEqualObjects(request.APIKey, kAPIKey);
+        XCTAssertEqualObjects(request.email, kEmail);
+        XCTAssertEqualObjects(request.password, kFakePassword);
+        XCTAssertTrue(request.returnSecureToken);
+        dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
+          id mockVerifyPasswordResponse = OCMClassMock([FIRVerifyPasswordResponse class]);
+          [self stubTokensWithMockResponse:mockVerifyPasswordResponse];
+          callback(mockVerifyPasswordResponse, nil);
+        });
+      });
+  [self expectGetAccountInfo];
+  XCTestExpectation *signInExpectation = [self expectationWithDescription:@"signIn"];
+  [[FIRAuth auth] signOut:NULL];
+  [[FIRAuth auth] signInWithEmail:kEmail
+                         password:kFakePassword
+                       completion:^(FIRAuthDataResult *_Nullable result, NSError *_Nullable error) {
+                         [self assertUser:result.user];
+                         XCTAssertNil(error);
+                         [signInExpectation fulfill];
+                       }];
+  [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
+  [self assertUser:[FIRAuth auth].currentUser];
+  id mockSecureTokenResponse = OCMClassMock([FIRSecureTokenResponse class]);
+  OCMStub([mockSecureTokenResponse accessToken]).andReturn(@"IDToken");
+  OCMExpect([self->_mockBackend secureToken:[OCMArg any] callback:[OCMArg any]])
+      .andCallBlock2(
+          ^(FIRSecureTokenRequest *_Nullable request, FIRSecureTokenResponseCallback callback) {
+            dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
+              callback(mockSecureTokenResponse, nil);
+            });
+          });
+  XCTestExpectation *revokeExpectation = [self expectationWithDescription:@"revoke"];
+  OCMExpect([_mockBackend revokeToken:[OCMArg any] callback:[OCMArg any]])
+      .andCallBlock2(
+          ^(FIRRevokeTokenRequest *_Nullable request, FIRRevokeTokenResponseCallback callback) {
+            dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
+              id mockRevokeTokenResponse = OCMClassMock([FIRRevokeTokenResponse class]);
+              callback(mockRevokeTokenResponse, nil);
+              [revokeExpectation fulfill];
+            });
+          });
+  NSString *code = @"code";
+  [[FIRAuth auth] revokeTokenWithAuthorizationCode:code completion:nil];
+  [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
+}
+
 @end

+ 124 - 0
FirebaseAuth/Tests/Unit/FIRRevokeTokenRequestTests.m

@@ -0,0 +1,124 @@
+/*
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import <TargetConditionals.h>
+#if TARGET_OS_IOS
+
+#import <XCTest/XCTest.h>
+
+#import "FirebaseAuth/Sources/Backend/FIRAuthBackend.h"
+#import "FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenRequest.h"
+#import "FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenResponse.h"
+#import "FirebaseAuth/Tests/Unit/FIRFakeBackendRPCIssuer.h"
+
+/** @var kFakeToken
+    @brief The fake token to use in the test request.
+ */
+static NSString *const kFakeTokenKey = @"token";
+
+/** @var kFakeToken
+    @brief The fake token to use in the test request.
+ */
+static NSString *const kFakeToken = @"fakeToken";
+
+/** @var kFakeIDToken
+    @brief The fake ID token to use in the test request.
+ */
+static NSString *const kFakeIDTokenKey = @"idToken";
+
+/** @var kFakeIDToken
+    @brief The fake ID token to use in the test request.
+ */
+static NSString *const kFakeIDToken = @"fakeIDToken";
+
+/** @var kFakeProviderIDKey
+    @brief The fake provider id key to use in the test request.
+ */
+static NSString *const kFakeProviderIDKey = @"providerId";
+
+/** @var kFakeTokenTypeKey
+    @brief The fake ID token to use in the test request.
+ */
+static NSString *const kFakeTokenTypeKey = @"tokenType";
+
+/** @var kFakeAPIKey
+    @brief The fake API key to use in the test request.
+ */
+static NSString *const kFakeAPIKey = @"APIKey";
+
+/** @var kFakeFirebaseAppID
+    @brief The fake Firebase app ID to use in the test request.
+ */
+static NSString *const kFakeFirebaseAppID = @"appID";
+
+/** @var kExpectedAPIURL
+    @brief The expected URL for the test calls.
+ */
+static NSString *const kExpectedAPIURL =
+    @"https://identitytoolkit.googleapis.com/v2/accounts:revokeToken?key=APIKey";
+
+/** @class FIRRevokeTokenRequestTest
+    @brief Tests for @c FIRRevokeTokenRequests.
+ */
+@interface FIRRevokeTokenRequestTest : XCTestCase
+@end
+
+@implementation FIRRevokeTokenRequestTest {
+  /** @var _RPCIssuer
+      @brief This backend RPC issuer is used to fake network responses for each test in the suite.
+          In the @c setUp method we initialize this and set @c FIRAuthBackend's RPC issuer to it.
+   */
+  FIRFakeBackendRPCIssuer *_RPCIssuer;
+}
+
+- (void)setUp {
+  [super setUp];
+  FIRFakeBackendRPCIssuer *RPCIssuer = [[FIRFakeBackendRPCIssuer alloc] init];
+  [FIRAuthBackend setDefaultBackendImplementationWithRPCIssuer:RPCIssuer];
+  _RPCIssuer = RPCIssuer;
+}
+
+- (void)tearDown {
+  _RPCIssuer = nil;
+  [FIRAuthBackend setDefaultBackendImplementationWithRPCIssuer:nil];
+  [super tearDown];
+}
+
+/** @fn testRevokeTokenRequest
+    @brief Tests the token revocation request.
+ */
+- (void)testRevokeTokenRequest {
+  FIRAuthRequestConfiguration *requestConfiguration =
+      [[FIRAuthRequestConfiguration alloc] initWithAPIKey:kFakeAPIKey appID:kFakeFirebaseAppID];
+  FIRRevokeTokenRequest *request =
+      [[FIRRevokeTokenRequest alloc] initWithToken:kFakeToken
+                                           idToken:kFakeIDToken
+                              requestConfiguration:requestConfiguration];
+  [FIRAuthBackend
+      revokeToken:request
+         callback:^(FIRRevokeTokenResponse *_Nullable response, NSError *_Nullable error){
+         }];
+  XCTAssertEqualObjects(_RPCIssuer.requestURL.absoluteString, kExpectedAPIURL);
+  XCTAssertNotNil(_RPCIssuer.decodedRequest);
+  XCTAssertEqualObjects(_RPCIssuer.decodedRequest[kFakeIDTokenKey], kFakeIDToken);
+  XCTAssertEqualObjects(_RPCIssuer.decodedRequest[kFakeTokenKey], kFakeToken);
+  XCTAssertEqualObjects(_RPCIssuer.decodedRequest[kFakeProviderIDKey], @"apple.com");
+  XCTAssertEqual([_RPCIssuer.decodedRequest[kFakeTokenTypeKey] intValue], 3);
+}
+
+@end
+
+#endif

+ 117 - 0
FirebaseAuth/Tests/Unit/FIRRevokeTokenResponseTests.m

@@ -0,0 +1,117 @@
+/*
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import <TargetConditionals.h>
+#if TARGET_OS_IOS
+
+#import <XCTest/XCTest.h>
+
+#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIRAuthErrors.h"
+
+#import "FirebaseAuth/Sources/Backend/FIRAuthBackend.h"
+#import "FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenRequest.h"
+#import "FirebaseAuth/Sources/Backend/RPC/FIRRevokeTokenResponse.h"
+#import "FirebaseAuth/Tests/Unit/FIRFakeBackendRPCIssuer.h"
+
+/** @var kFakeToken
+    @brief The fake token to use in the test request.
+ */
+static NSString *const kFakeToken = @"fakeToken";
+
+/** @var kFakeIDToken
+    @brief The fake ID token to use in the test request.
+ */
+static NSString *const kFakeIDToken = @"fakeIDToken";
+
+/** @var kFakeToken
+    @brief The fake token to use in the test request.
+ */
+static NSString *const kFakeTokenKey = @"tokenKey";
+
+/** @var kFakeIDToken
+    @brief The fake ID token to use in the test request.
+ */
+static NSString *const kFakeIDTokenKey = @"idTokenKey";
+
+/** @var kFakeAPIKey
+    @brief The fake API key to use in the test request.
+ */
+static NSString *const kFakeAPIKey = @"APIKey";
+
+/** @var kFakeFirebaseAppID
+    @brief The fake Firebase app ID to use in the test request.
+ */
+static NSString *const kFakeFirebaseAppID = @"appID";
+
+/** @var kExpectedAPIURL
+    @brief The expected URL for the test calls.
+ */
+static NSString *const kExpectedAPIURL =
+    @"https://www.googleapis.com/identitytoolkit/v3/relyingparty/revokeToken?key=APIKey";
+
+@interface FIRRevokeTokenResponseTests : XCTestCase
+@end
+
+@implementation FIRRevokeTokenResponseTests {
+  /** @var _RPCIssuer
+      @brief This backend RPC issuer is used to fake network responses for each test in the suite.
+          In the @c setUp method we initialize this and set @c FIRAuthBackend's RPC issuer to it.
+   */
+  FIRFakeBackendRPCIssuer *_RPCIssuer;
+
+  /** @var _requestConfiguration
+      @brief This is the request configuration used for testing.
+   */
+  FIRAuthRequestConfiguration *_requestConfiguration;
+}
+
+- (void)setUp {
+  [super setUp];
+  FIRFakeBackendRPCIssuer *RPCIssuer = [[FIRFakeBackendRPCIssuer alloc] init];
+  [FIRAuthBackend setDefaultBackendImplementationWithRPCIssuer:RPCIssuer];
+  _RPCIssuer = RPCIssuer;
+  _requestConfiguration = [[FIRAuthRequestConfiguration alloc] initWithAPIKey:kFakeAPIKey
+                                                                        appID:kFakeFirebaseAppID];
+}
+
+/** @fn testSuccessfulRevokeTokenResponse
+    @brief Tests a succesful attempt of the token revocation flow.
+ */
+- (void)testSuccessfulResponse {
+  FIRRevokeTokenRequest *request =
+      [[FIRRevokeTokenRequest alloc] initWithToken:kFakeToken
+                                           idToken:kFakeIDToken
+                              requestConfiguration:_requestConfiguration];
+  __block BOOL callbackInvoked;
+  __block FIRRevokeTokenResponse *RPCResponse;
+  __block NSError *RPCError;
+  [FIRAuthBackend
+      revokeToken:request
+         callback:^(FIRRevokeTokenResponse *_Nullable response, NSError *_Nullable error) {
+           RPCResponse = response;
+           RPCError = error;
+           callbackInvoked = YES;
+         }];
+
+  [_RPCIssuer respondWithJSON:@{}];
+
+  XCTAssert(callbackInvoked);
+  XCTAssertNotNil(RPCResponse);
+}
+
+@end
+
+#endif

+ 4 - 0
FirebaseCore/CHANGELOG.md

@@ -1,3 +1,7 @@
+# Firebase 10.8.0
+- Fix new build warnings introduced by Xcode 14.3. (#11059)
+- [changed] The Firebase Swift package now requires the Swift 5.6 toolchain (Xcode 13.3) to build.
+
 # Firebase 10.4.0
 - Deprecate `androidClientID` and `trackingID` from FirebaseOptions. (#10520)
 

+ 1 - 0
FirebaseDatabaseSwift/Sources/Codable/DataSnapshot+ReadDecodable.swift

@@ -16,6 +16,7 @@
 
 import Foundation
 import FirebaseDatabase
+import FirebaseSharedSwift
 
 public extension DataSnapshot {
   /// Retrieves the value of a snapshot and converts it to an instance of

+ 1 - 0
FirebaseDatabaseSwift/Sources/Codable/DatabaseReference+WriteEncodable.swift

@@ -16,6 +16,7 @@
 
 import Foundation
 import FirebaseDatabase
+import FirebaseSharedSwift
 
 public extension DatabaseReference {
   /// Encodes an instance of `Encodable` and overwrites the encoded data

+ 4 - 4
FirebaseMessaging/Sources/FIRMessagingUtilities.m

@@ -39,7 +39,7 @@ static NSString *const kAPSEnvironmentDevelopmentValue = @"development";
 
 #pragma mark - URL Helpers
 
-NSString *FIRMessagingTokenRegisterServer() {
+NSString *FIRMessagingTokenRegisterServer(void) {
   return @"https://fcmtoken.googleapis.com/register";
 }
 
@@ -91,7 +91,7 @@ NSString *FIRMessagingAppIdentifier(void) {
 #endif
 }
 
-NSString *FIRMessagingFirebaseAppID() {
+NSString *FIRMessagingFirebaseAppID(void) {
   return [FIROptions defaultOptions].googleAppID;
 }
 
@@ -273,7 +273,7 @@ NSArray *FIRMessagingFirebaseLocales(void) {
   return locales;
 }
 
-NSString *FIRMessagingCurrentLocale() {
+NSString *FIRMessagingCurrentLocale(void) {
   NSArray *locales = FIRMessagingFirebaseLocales();
   NSArray *preferredLocalizations =
       [NSBundle preferredLocalizationsFromArray:locales
@@ -283,7 +283,7 @@ NSString *FIRMessagingCurrentLocale() {
   return legalDocsLanguage ? legalDocsLanguage : @"en";
 }
 
-BOOL FIRMessagingHasLocaleChanged() {
+BOOL FIRMessagingHasLocaleChanged(void) {
   NSString *lastLocale = [[GULUserDefaults standardUserDefaults]
       stringForKey:kFIRMessagingInstanceIDUserDefaultsKeyLocale];
   NSString *currentLocale = FIRMessagingCurrentLocale();

+ 0 - 2
FirebaseTestingSupport/Firestore/Sources/FIRQueryFake.mm

@@ -14,8 +14,6 @@
 
 #import "FirebaseTestingSupport/Firestore/Sources/Public/FirebaseFirestoreTestingSupport/FIRQueryFake.h"
 
-#import "Firestore/Source/API/FIRQuery+Internal.h"
-
 @implementation FIRQueryFake
 
 - (instancetype)init {

+ 5 - 0
Firestore/CHANGELOG.md

@@ -1,3 +1,8 @@
+# 10.8.0
+- [feature] Change Firestore's Swift Package Manager distribution from source
+  to binary to reduce the time it takes to add the Firebase package and to
+  build the Firestore SDK (#6564).
+
 # 10.7.0
 - [feature] Add support for disjunctions in queries (`OR` queries).
 - [fixed] Fixed stack overflow caused by deeply nested server timestamps.

+ 0 - 6
Firestore/core/include/firebase/firestore/timestamp.h

@@ -104,16 +104,13 @@ class Timestamp {
    * Converts `time_t` to a `Timestamp`.
    *
    * @param seconds_since_unix_epoch
-   *     @parblock
    *     The number of seconds of UTC time since Unix epoch
    *     1970-01-01T00:00:00Z. Can be negative to represent dates before the
    *     epoch. Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z
    *     inclusive; otherwise, assertion failure will be triggered.
-   *
    *     Note that while the epoch of `time_t` is unspecified, it's usually Unix
    *     epoch. If this assumption is broken, this function will produce
    *     incorrect results.
-   *     @endparblock
    *
    * @return a new timestamp with the given number of seconds and zero
    *     nanoseconds.
@@ -125,17 +122,14 @@ class Timestamp {
    * Converts `std::chrono::time_point` to a `Timestamp`.
    *
    * @param time_point
-   *     @parblock
    *     The time point with system clock's epoch, which is
    *     presumed to be Unix epoch 1970-01-01T00:00:00Z. Can be negative to
    *     represent dates before the epoch. Must be from 0001-01-01T00:00:00Z to
    *     9999-12-31T23:59:59Z inclusive; otherwise, assertion failure will be
    *     triggered.
-   *
    *     Note that while the epoch of `std::chrono::system_clock` is
    *     unspecified, it's usually Unix epoch. If this assumption is broken,
    *     this constructor will produce incorrect results.
-   *     @endparblock
    */
   static Timestamp FromTimePoint(
       std::chrono::time_point<std::chrono::system_clock> time_point);

+ 1 - 1
GoogleAppMeasurement.podspec

@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
     s.authors          = 'Google, Inc.'
 
     s.source           = {
-        :http => 'https://dl.google.com/firebase/ios/analytics/93d139ae9f688e9c/GoogleAppMeasurement-10.6.0.tar.gz'
+        :http => 'https://dl.google.com/firebase/ios/analytics/c63c2bcbdb7c6785/GoogleAppMeasurement-10.8.0.tar.gz'
     }
 
     s.cocoapods_version = '>= 1.10.2'

+ 95 - 152
Package.swift

@@ -1,4 +1,4 @@
-// swift-tools-version:5.3
+// swift-tools-version:5.6
 // The swift-tools-version declares the minimum version of Swift required to
 // build this package.
 
@@ -23,7 +23,7 @@ let firebaseVersion = "10.8.0"
 
 let package = Package(
   name: "Firebase",
-  platforms: [.iOS(.v11), .macOS(.v10_13), .tvOS(.v12), .watchOS(.v7)],
+  platforms: [.iOS(.v11), .macCatalyst(.v13), .macOS(.v10_13), .tvOS(.v12), .watchOS(.v7)],
   products: [
     .library(
       name: "FirebaseAnalytics",
@@ -136,66 +136,49 @@ let package = Package(
   ],
   dependencies: [
     .package(
-      name: "Promises",
       url: "https://github.com/google/promises.git",
       "2.1.0" ..< "3.0.0"
     ),
     .package(
-      name: "SwiftProtobuf",
       url: "https://github.com/apple/swift-protobuf.git",
       "1.19.0" ..< "2.0.0"
     ),
+    googleAppMeasurementDependency(),
     .package(
-      name: "GoogleAppMeasurement",
-      url: "https://github.com/google/GoogleAppMeasurement.git",
-      // Note that CI changes the version to the head of main for CI.
-      // See scripts/setup_spm_tests.sh.
-      .exact("10.6.0")
-    ),
-    .package(
-      name: "GoogleDataTransport",
       url: "https://github.com/google/GoogleDataTransport.git",
       "9.2.0" ..< "10.0.0"
     ),
     .package(
-      name: "GoogleUtilities",
       url: "https://github.com/google/GoogleUtilities.git",
       "7.10.0" ..< "8.0.0"
     ),
     .package(
-      name: "GTMSessionFetcher",
       url: "https://github.com/google/gtm-session-fetcher.git",
       "2.1.0" ..< "4.0.0"
     ),
     .package(
-      name: "nanopb",
       url: "https://github.com/firebase/nanopb.git",
       "2.30909.0" ..< "2.30910.0"
     ),
     .package(
-      name: "abseil",
-      url: "https://github.com/firebase/abseil-cpp-SwiftPM.git",
-      "0.20220203.1" ..< "0.20220204.0"
+      url: "https://github.com/google/abseil-cpp-binary.git",
+      "1.2021110200.0" ..< "1.2021110300.0"
     ),
     .package(
-      name: "gRPC",
-      url: "https://github.com/grpc/grpc-ios.git",
-      "1.44.0-grpc" ..< "1.45.0-grpc"
+      url: "https://github.com/google/grpc-binary.git",
+      "1.44.0" ..< "1.45.0"
     ),
     .package(
-      name: "OCMock",
       url: "https://github.com/erikdoe/ocmock.git",
-      .revision("c5eeaa6dde7c308a5ce48ae4d4530462dd3a1110")
+      revision: "c5eeaa6dde7c308a5ce48ae4d4530462dd3a1110"
     ),
     .package(
-      name: "leveldb",
       url: "https://github.com/firebase/leveldb.git",
       "1.22.2" ..< "1.23.0"
     ),
     .package(
-      name: "GCDWebServer",
       url: "https://github.com/SlaunchaMan/GCDWebServer.git",
-      .revision("935e2736044e71e5341663c3cc9a335ba6867a2b")
+      revision: "935e2736044e71e5341663c3cc9a335ba6867a2b"
     ),
   ],
   targets: [
@@ -220,7 +203,7 @@ let package = Package(
         // TODO: - Add support for cflags cSetting so that we can set the -fno-autolink option
       ],
       linkerSettings: [
-        .linkedFramework("UIKit", .when(platforms: [.iOS, .tvOS])),
+        .linkedFramework("UIKit", .when(platforms: [.iOS, .macCatalyst, .tvOS])),
         .linkedFramework("AppKit", .when(platforms: [.macOS])),
       ]
     ),
@@ -230,7 +213,7 @@ let package = Package(
         "FirebaseCore",
         "SharedTestUtilities",
         "HeartbeatLoggingTestUtils",
-        "OCMock",
+        .product(name: "OCMock", package: "ocmock"),
       ],
       path: "FirebaseCore/Tests/Unit",
       exclude: ["Resources/GoogleService-Info.plist"],
@@ -288,7 +271,7 @@ let package = Package(
     ),
     .testTarget(
       name: "ABTestingUnit",
-      dependencies: ["FirebaseABTesting", "OCMock"],
+      dependencies: ["FirebaseABTesting", .product(name: "OCMock", package: "ocmock")],
       path: "FirebaseABTesting/Tests/Unit",
       resources: [.process("Resources")],
       cSettings: [
@@ -299,17 +282,20 @@ let package = Package(
     .target(
       name: "FirebaseAnalyticsTarget",
       dependencies: [.target(name: "FirebaseAnalyticsWrapper",
-                             condition: .when(platforms: [.iOS, .macOS, .tvOS]))],
+                             condition: .when(platforms: [.iOS, .macCatalyst, .macOS, .tvOS]))],
       path: "SwiftPM-PlatformExclude/FirebaseAnalyticsWrap"
     ),
 
     .target(
       name: "FirebaseAnalyticsWrapper",
       dependencies: [
-        .target(name: "FirebaseAnalytics", condition: .when(platforms: [.iOS, .macOS, .tvOS])),
+        .target(
+          name: "FirebaseAnalytics",
+          condition: .when(platforms: [.iOS, .macCatalyst, .macOS, .tvOS])
+        ),
         .product(name: "GoogleAppMeasurement",
                  package: "GoogleAppMeasurement",
-                 condition: .when(platforms: [.iOS, .macOS, .tvOS])),
+                 condition: .when(platforms: [.iOS, .macCatalyst, .macOS, .tvOS])),
         "FirebaseCore",
         "FirebaseInstallations",
         .product(name: "GULAppDelegateSwizzler", package: "GoogleUtilities"),
@@ -328,13 +314,13 @@ let package = Package(
     ),
     .binaryTarget(
       name: "FirebaseAnalytics",
-      url: "https://dl.google.com/firebase/ios/swiftpm/10.6.0/FirebaseAnalytics.zip",
-      checksum: "a893066f524130a007ee255d9e535879b96a3fa0add139a8245edaf1c2f310f6"
+      url: "https://dl.google.com/firebase/ios/swiftpm/10.8.0/FirebaseAnalytics.zip",
+      checksum: "f758786d204e2139d221bd91ac0767514845a507affe7d0a268563b2746ebf02"
     ),
     .target(
       name: "FirebaseAnalyticsSwiftTarget",
       dependencies: [.target(name: "FirebaseAnalyticsSwift",
-                             condition: .when(platforms: [.iOS, .macOS, .tvOS]))],
+                             condition: .when(platforms: [.iOS, .macCatalyst, .macOS, .tvOS]))],
       path: "SwiftPM-PlatformExclude/FirebaseAnalyticsSwiftWrap"
     ),
     .target(
@@ -346,16 +332,19 @@ let package = Package(
     .target(
       name: "FirebaseAnalyticsWithoutAdIdSupportTarget",
       dependencies: [.target(name: "FirebaseAnalyticsWithoutAdIdSupportWrapper",
-                             condition: .when(platforms: [.iOS, .macOS, .tvOS]))],
+                             condition: .when(platforms: [.iOS, .macCatalyst, .macOS, .tvOS]))],
       path: "SwiftPM-PlatformExclude/FirebaseAnalyticsWithoutAdIdSupportWrap"
     ),
     .target(
       name: "FirebaseAnalyticsWithoutAdIdSupportWrapper",
       dependencies: [
-        .target(name: "FirebaseAnalytics", condition: .when(platforms: [.iOS, .macOS, .tvOS])),
+        .target(
+          name: "FirebaseAnalytics",
+          condition: .when(platforms: [.iOS, .macCatalyst, .macOS, .tvOS])
+        ),
         .product(name: "GoogleAppMeasurementWithoutAdIdSupport",
                  package: "GoogleAppMeasurement",
-                 condition: .when(platforms: [.iOS])),
+                 condition: .when(platforms: [.iOS, .macCatalyst, .macOS, .tvOS])),
         "FirebaseCore",
         "FirebaseInstallations",
         .product(name: "GULAppDelegateSwizzler", package: "GoogleUtilities"),
@@ -408,7 +397,7 @@ let package = Package(
     ),
     .testTarget(
       name: "AppDistributionUnit",
-      dependencies: ["FirebaseAppDistribution", "OCMock"],
+      dependencies: ["FirebaseAppDistribution", .product(name: "OCMock", package: "ocmock")],
       path: "FirebaseAppDistribution/Tests/Unit",
       exclude: ["Swift/"],
       resources: [.process("Resources")],
@@ -431,7 +420,7 @@ let package = Package(
         "FirebaseCore",
         .product(name: "GULAppDelegateSwizzler", package: "GoogleUtilities"),
         .product(name: "GULEnvironment", package: "GoogleUtilities"),
-        .product(name: "GTMSessionFetcherCore", package: "GTMSessionFetcher"),
+        .product(name: "GTMSessionFetcherCore", package: "gtm-session-fetcher"),
       ],
       path: "FirebaseAuth/Sources",
       publicHeadersPath: "Public",
@@ -457,7 +446,11 @@ let package = Package(
     ),
     .testTarget(
       name: "AuthUnit",
-      dependencies: ["FirebaseAuth", "OCMock", "HeartbeatLoggingTestUtils"],
+      dependencies: [
+        "FirebaseAuth",
+        "HeartbeatLoggingTestUtils",
+        .product(name: "OCMock", package: "ocmock"),
+      ],
       path: "FirebaseAuth/Tests/Unit",
       exclude: [
         "FIRAuthKeychainServicesTests.m", // TODO: figure out SPM keychain testing
@@ -476,7 +469,7 @@ let package = Package(
     .target(
       name: "FirebaseFirestoreCombineSwift",
       dependencies: [
-        "FirebaseFirestore",
+        "FirebaseFirestoreTarget",
         "FirebaseFirestoreSwift",
       ],
       path: "FirebaseCombineSwift/Sources/Firestore"
@@ -532,7 +525,7 @@ let package = Package(
     ),
     .testTarget(
       name: "FirebaseCrashlyticsUnit",
-      dependencies: ["FirebaseCrashlytics", "OCMock"],
+      dependencies: ["FirebaseCrashlytics", .product(name: "OCMock", package: "ocmock")],
       path: "Crashlytics/UnitTests",
       resources: [
         .copy("FIRCLSMachO/machO_data"),
@@ -573,7 +566,11 @@ let package = Package(
     ),
     .testTarget(
       name: "DatabaseUnit",
-      dependencies: ["FirebaseDatabase", "OCMock", "SharedTestUtilities"],
+      dependencies: [
+        "FirebaseDatabase",
+        "SharedTestUtilities",
+        .product(name: "OCMock", package: "ocmock"),
+      ],
       path: "FirebaseDatabase/Tests/",
       exclude: [
         // Disable Swift tests as mixed targets are not supported (Xcode 12.4).
@@ -640,73 +637,24 @@ let package = Package(
 
     .target(
       name: "FirebaseFirestoreTarget",
-      dependencies: [.target(name: "FirebaseFirestore",
-                             condition: .when(platforms: [.iOS, .tvOS, .macOS]))],
-      path: "SwiftPM-PlatformExclude/FirebaseFirestoreWrap"
-    ),
-
-    .target(
-      name: "FirebaseFirestore",
       dependencies: [
+        .target(
+          name: "FirebaseFirestore",
+          condition: .when(platforms: [.iOS, .tvOS, .macOS])
+        ),
+        .product(name: "abseil", package: "abseil-cpp-binary"),
+        .product(name: "gRPC-C++", package: "grpc-binary"),
+        .product(name: "nanopb", package: "nanopb"),
         "FirebaseCore",
         "leveldb",
-        .product(name: "nanopb", package: "nanopb"),
-        .product(name: "abseil", package: "abseil"),
-        .product(name: "gRPC-cpp", package: "gRPC"),
       ],
-      path: "Firestore",
-      exclude: [
-        "CHANGELOG.md",
-        "CMakeLists.txt",
-        "Example/",
-        "LICENSE",
-        "Protos/CMakeLists.txt",
-        "Protos/Podfile",
-        "Protos/README.md",
-        "Protos/build_protos.py",
-        "Protos/cpp/",
-        "Protos/lib/",
-        "Protos/nanopb_cpp_generator.py",
-        "Protos/protos/",
-        "README.md",
-        "Source/CMakeLists.txt",
-        "Swift/",
-        "core/CMakeLists.txt",
-        "core/src/util/config_detected.h.in",
-        "core/test/",
-        "fuzzing/",
-        "test.sh",
-        // Swift PM doesn't recognize hpp files, so we're relying on search paths
-        // to find third_party/nlohmann_json/json.hpp.
-        "third_party/",
+      path: "SwiftPM-PlatformExclude/FirebaseFirestoreWrap"
+    ),
 
-        // Exclude alternate implementations for other platforms
-        "core/src/remote/connectivity_monitor_noop.cc",
-        "core/src/util/filesystem_win.cc",
-        "core/src/util/log_stdio.cc",
-        "core/src/util/secure_random_openssl.cc",
-      ],
-      sources: [
-        "Source/",
-        "Protos/nanopb/",
-        "core/include/",
-        "core/src",
-      ],
-      publicHeadersPath: "Source/Public",
-      cSettings: [
-        .headerSearchPath("../"),
-        .headerSearchPath("Source/Public/FirebaseFirestore"),
-        .headerSearchPath("Protos/nanopb"),
-        .define("PB_FIELD_32BIT", to: "1"),
-        .define("PB_NO_PACKED_STRUCTS", to: "1"),
-        .define("PB_ENABLE_MALLOC", to: "1"),
-        .define("FIRFirestore_VERSION", to: firebaseVersion),
-      ],
-      linkerSettings: [
-        .linkedFramework("SystemConfiguration", .when(platforms: [.iOS, .macOS, .tvOS])),
-        .linkedFramework("UIKit", .when(platforms: [.iOS, .tvOS])),
-        .linkedLibrary("c++"),
-      ]
+    .binaryTarget(
+      name: "FirebaseFirestore",
+      url: "https://dl.google.com/firebase/ios/bin/firestore/10.8.0/FirebaseFirestore.zip",
+      checksum: "56ea3c98343cc31e3579faf5292ec73223c86e6502848ad2bf4870f6cbc63104"
     ),
 
     .target(
@@ -721,7 +669,7 @@ let package = Package(
       dependencies: [
         "FirebaseCore",
         "FirebaseCoreExtension",
-        "FirebaseFirestore",
+        "FirebaseFirestoreTarget",
         "FirebaseSharedSwift",
       ],
       path: "Firestore",
@@ -757,7 +705,7 @@ let package = Package(
         "FirebaseCoreExtension",
         "FirebaseMessagingInterop",
         "FirebaseSharedSwift",
-        .product(name: "GTMSessionFetcherCore", package: "GTMSessionFetcher"),
+        .product(name: "GTMSessionFetcherCore", package: "gtm-session-fetcher"),
       ],
       path: "FirebaseFunctions/Sources"
     ),
@@ -875,7 +823,7 @@ let package = Package(
         "FirebaseInstallations",
         .product(name: "GoogleDataTransport", package: "GoogleDataTransport"),
         .product(name: "GULLogger", package: "GoogleUtilities"),
-        "SwiftProtobuf",
+        .product(name: "SwiftProtobuf", package: "swift-protobuf"),
       ],
       path: "FirebaseMLModelDownloader/Sources",
       exclude: [
@@ -926,7 +874,11 @@ let package = Package(
     ),
     .testTarget(
       name: "MessagingUnit",
-      dependencies: ["FirebaseMessaging", "SharedTestUtilities", "OCMock"],
+      dependencies: [
+        "FirebaseMessaging",
+        "SharedTestUtilities",
+        .product(name: "OCMock", package: "ocmock"),
+      ],
       path: "FirebaseMessaging/Tests/UnitTests",
       exclude: [
         "FIRMessagingContextManagerServiceTest.m", // TODO: Adapt its NSBundle usage to SPM.
@@ -975,9 +927,9 @@ let package = Package(
       name: "PerformanceUnit",
       dependencies: [
         "FirebasePerformanceTarget",
-        "OCMock",
         "SharedTestUtilities",
         "GCDWebServer",
+        .product(name: "OCMock", package: "ocmock"),
       ],
       path: "FirebasePerformance/Tests/Unit",
       resources: [
@@ -1000,7 +952,7 @@ let package = Package(
                      "FirebaseAuthInterop",
                      "FirebaseMessagingInterop",
                      "GoogleDataTransport",
-                     "OCMock"],
+                     .product(name: "OCMock", package: "ocmock")],
       path: "SharedTestUtilities",
       publicHeadersPath: "./",
       cSettings: [
@@ -1026,7 +978,7 @@ let package = Package(
     ),
     .testTarget(
       name: "RemoteConfigUnit",
-      dependencies: ["FirebaseRemoteConfig", "OCMock"],
+      dependencies: ["FirebaseRemoteConfig", .product(name: "OCMock", package: "ocmock")],
       path: "FirebaseRemoteConfig/Tests/Unit",
       exclude: [
         // Need to be evaluated/ported to RC V2.
@@ -1072,7 +1024,7 @@ let package = Package(
     ),
     .target(
       name: "RemoteConfigFakeConsoleObjC",
-      dependencies: ["OCMock"],
+      dependencies: [.product(name: "OCMock", package: "ocmock")],
       path: "FirebaseRemoteConfigSwift/Tests/ObjC",
       publicHeadersPath: ".",
       cSettings: [
@@ -1103,7 +1055,10 @@ let package = Package(
       ],
       linkerSettings: [
         .linkedFramework("Security"),
-        .linkedFramework("SystemConfiguration", .when(platforms: [.iOS, .macOS, .tvOS])),
+        .linkedFramework(
+          "SystemConfiguration",
+          .when(platforms: [.iOS, .macCatalyst, .macOS, .tvOS])
+        ),
       ]
     ),
     // The Sessions SDK is Swift-first with Objective-C code to support
@@ -1136,7 +1091,10 @@ let package = Package(
       ],
       linkerSettings: [
         .linkedFramework("Security"),
-        .linkedFramework("SystemConfiguration", .when(platforms: [.iOS, .macOS, .tvOS])),
+        .linkedFramework(
+          "SystemConfiguration",
+          .when(platforms: [.iOS, .macCatalyst, .macOS, .tvOS])
+        ),
       ]
     ),
     .testTarget(
@@ -1154,7 +1112,7 @@ let package = Package(
         "FirebaseAuthInterop",
         "FirebaseCore",
         "FirebaseCoreExtension",
-        .product(name: "GTMSessionFetcherCore", package: "GTMSessionFetcher"),
+        .product(name: "GTMSessionFetcherCore", package: "gtm-session-fetcher"),
       ],
       path: "FirebaseStorage/Sources"
     ),
@@ -1200,7 +1158,7 @@ let package = Package(
         "FirebaseCore",
         "FirebaseDatabase",
         "FirebaseDynamicLinks",
-        "FirebaseFirestore",
+        "FirebaseFirestoreTarget",
         "FirebaseFirestoreSwift",
         "FirebaseFunctions",
         "FirebaseInAppMessaging",
@@ -1239,7 +1197,7 @@ let package = Package(
         "FirebaseCore",
         "FirebaseDatabase",
         "FirebaseDynamicLinks",
-        "FirebaseFirestore",
+        "FirebaseFirestoreTarget",
         "FirebaseFunctions",
         "FirebaseInAppMessaging",
         "FirebaseInstallations",
@@ -1276,7 +1234,10 @@ let package = Package(
               .headerSearchPath("../.."),
             ],
             linkerSettings: [
-              .linkedFramework("DeviceCheck", .when(platforms: [.iOS, .macOS, .tvOS])),
+              .linkedFramework(
+                "DeviceCheck",
+                .when(platforms: [.iOS, .macCatalyst, .macOS, .tvOS])
+              ),
             ]),
     // Internal headers only for consuming from Swift.
     .target(
@@ -1294,9 +1255,9 @@ let package = Package(
       name: "AppCheckUnit",
       dependencies: [
         "FirebaseAppCheck",
-        "OCMock",
         "SharedTestUtilities",
         "HeartbeatLoggingTestUtils",
+        .product(name: "OCMock", package: "ocmock"),
       ],
       path: "FirebaseAppCheck/Tests",
       exclude: [
@@ -1323,7 +1284,7 @@ let package = Package(
 
     .target(
       name: "FirebaseFirestoreTestingSupport",
-      dependencies: ["FirebaseFirestore"],
+      dependencies: ["FirebaseFirestoreTarget"],
       path: "FirebaseTestingSupport/Firestore/Sources",
       publicHeadersPath: "./",
       cSettings: [
@@ -1345,17 +1306,6 @@ let package = Package(
   cxxLanguageStandard: CXXLanguageStandard.gnucxx14
 )
 
-if ProcessInfo.processInfo.environment["FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT"] != nil {
-  if let GoogleAppMeasurementIndex = package.dependencies
-    .firstIndex(where: { $0.name == "GoogleAppMeasurement" }) {
-    package.dependencies[GoogleAppMeasurementIndex] = .package(
-      name: "GoogleAppMeasurement",
-      url: "https://github.com/google/GoogleAppMeasurement.git",
-      .branch("main")
-    )
-  }
-}
-
 // This is set when running `scripts/check_firestore_symbols.sh`.
 if ProcessInfo.processInfo.environment["FIREBASECI_USE_LOCAL_FIRESTORE_ZIP"] != nil {
   if let firestoreIndex = package.targets
@@ -1366,25 +1316,18 @@ if ProcessInfo.processInfo.environment["FIREBASECI_USE_LOCAL_FIRESTORE_ZIP"] !=
       path: "FirebaseFirestore.xcframework"
     )
   }
+}
 
-  // TODO(ncooke3): Below re-defining is not needed when original
-  // FirebaseFirestoreTarget definition matches below definition.
-  if let firestoreTargetIndex = package.targets
-    .firstIndex(where: { $0.name == "FirebaseFirestoreTarget" }) {
-    package.targets[firestoreTargetIndex] = .target(
-      name: "FirebaseFirestoreTarget",
-      dependencies: [
-        .target(
-          name: "FirebaseFirestore",
-          condition: .when(platforms: [.iOS, .tvOS, .macOS])
-        ),
-        .product(name: "abseil", package: "abseil"),
-        .product(name: "gRPC-cpp", package: "gRPC"),
-        .product(name: "nanopb", package: "nanopb"),
-        "FirebaseCore",
-        "leveldb",
-      ],
-      path: "SwiftPM-PlatformExclude/FirebaseFirestoreWrap"
-    )
+// MARK: - Helper Functions
+
+func googleAppMeasurementDependency() -> Package.Dependency {
+  let appMeasurementURL = "https://github.com/google/GoogleAppMeasurement.git"
+
+  // Point SPM CI to the tip of main of https://github.com/google/GoogleAppMeasurement so that the
+  // release process can defer publishing the GoogleAppMeasurement tag until after testing.
+  if ProcessInfo.processInfo.environment["FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT"] != nil {
+    return .package(url: appMeasurementURL, branch: "main")
   }
+
+  return .package(url: appMeasurementURL, exact: "10.8.0")
 }

+ 2 - 2
cmake/compiler_setup.cmake

@@ -14,8 +14,8 @@
 
 # C++ Compiler setup
 
-# We use C++11
-set(CMAKE_CXX_STANDARD 11)
+# We use C++14
+set(CMAKE_CXX_STANDARD 14)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 set(CMAKE_CXX_EXTENSIONS OFF)
 

+ 2 - 2
cmake/external/abseil-cpp.cmake

@@ -14,7 +14,7 @@
 
 include(ExternalProject)
 
-set(version 20211102.0)
+set(version 20220623.0)
 
 ExternalProject_Add(
   abseil-cpp
@@ -22,7 +22,7 @@ ExternalProject_Add(
   DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR}
   DOWNLOAD_NAME abseil-cpp-${version}.tar.gz
   URL https://github.com/abseil/abseil-cpp/archive/${version}.tar.gz
-  URL_HASH SHA256=dcf71b9cba8dc0ca9940c4b316a0c796be8fab42b070bb6b7cab62b48f0e66c4
+  URL_HASH SHA256=4208129b49006089ba1d6710845a45e31c59b0ab6bff9e5788a87f55c5abd602
 
   PREFIX ${PROJECT_BINARY_DIR}
 

+ 2 - 2
cmake/external/grpc.cmake

@@ -18,7 +18,7 @@ if(TARGET grpc)
   return()
 endif()
 
-set(version 1.44.0)
+set(version 1.50.0)
 
 ExternalProject_Add(
   grpc
@@ -26,7 +26,7 @@ ExternalProject_Add(
   DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR}
   DOWNLOAD_NAME grpc-${version}.tar.gz
   URL https://github.com/grpc/grpc/archive/v${version}.tar.gz
-  URL_HASH SHA256=8c05641b9f91cbc92f51cc4a5b3a226788d7a63f20af4ca7aaca50d92cc94a0d
+  URL_HASH SHA256=76900ab068da86378395a8e125b5cc43dfae671e09ff6462ddfef18676e2165a
 
   PREFIX ${PROJECT_BINARY_DIR}
   SOURCE_DIR ${PROJECT_BINARY_DIR}/src/grpc

+ 1 - 1
scripts/build.sh

@@ -171,7 +171,7 @@ watchos_flags=(
 )
 catalyst_flags=(
   ARCHS=x86_64 VALID_ARCHS=x86_64 SUPPORTS_MACCATALYST=YES -sdk macosx
-  -destination platform="macOS,variant=Mac Catalyst" TARGETED_DEVICE_FAMILY=2
+  -destination platform="macOS,variant=Mac Catalyst,arch=x86_64" TARGETED_DEVICE_FAMILY=2
   CODE_SIGN_IDENTITY=- CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
 )
 

+ 3 - 3
scripts/setup_spm_tests.sh

@@ -16,12 +16,12 @@
 
 
 # Point SPM CI to the tip of main of https://github.com/google/GoogleAppMeasurement
-# so that the release process can defer publish the GoogleAppMeasurement tag
+# so that the release process can defer publishing the GoogleAppMeasurement tag
 # until after testing.
 
-# For example: Change `.exact("8.3.1")` to `.branch("main")`
+# For example: Change `exact: "8.3.1"` to `branch: "main"`
 
-sed -i '' 's#exact("[0-9.]*#branch("main#' Package.swift
+sed -i '' 's#exact:[[:space:]]*"[0-9.]*"#branch: "main"#' Package.swift
 
 
 # Move schemes into place to run Swift Package Manager tests

+ 5 - 0
scripts/style.sh

@@ -63,6 +63,11 @@ esac
 # /usr/local.
 export MINT_PATH=Mint
 
+if ! which mint >/dev/null 2>&1; then
+  echo "mint is not available, install with 'brew install mint'"
+  exit 1
+fi
+
 system=$(uname -s)
 
 # Joins the given arguments with the separator given as the first argument.