SwiftAPI.swift 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. /*
  2. * Copyright 2022 Google LLC
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import Foundation
  17. import XCTest
  18. @testable import FirebaseAuth
  19. import FirebaseCore
  20. #if !os(macOS)
  21. import UIKit
  22. #endif
  23. /// This file tests public methods and enums. Properties are not included.
  24. /// Each function maps to a public header file.
  25. class AuthAPI_hOnlyTests: XCTestCase {
  26. // Each function corresponds with a public header.
  27. func FIRActionCodeSettings_h() {
  28. let codeSettings = FirebaseAuth.ActionCodeSettings()
  29. codeSettings.iOSBundleID = "abc"
  30. codeSettings.setAndroidPackageName("name", installIfNotAvailable: true, minimumVersion: "10.0")
  31. }
  32. func FIRAuth_h() throws {
  33. let auth = FirebaseAuth.Auth.auth()
  34. let authApp = FirebaseAuth.Auth.auth(app: FirebaseApp.app()!)
  35. let user = auth.currentUser!
  36. auth.updateCurrentUser(user) { _ in
  37. }
  38. authApp.fetchSignInMethods(forEmail: "abc@abc.com") { string, error in
  39. }
  40. auth.signIn(withEmail: "abc@abc.com", password: "password") { result, error in
  41. }
  42. auth.signIn(withEmail: "abc@abc.com", link: "link") { result, error in
  43. }
  44. #if !os(macOS)
  45. let provider = OAuthProvider(providerID: "abc")
  46. auth.signIn(with: OAuthProvider(providerID: "abc"), uiDelegate: nil) { result, error in
  47. }
  48. provider.getCredentialWith(nil) { credential, error in
  49. auth.signIn(with: credential!) { result, error in
  50. }
  51. }
  52. auth.signIn(with: OAuthProvider(providerID: "abc"), uiDelegate: nil) { result, error in
  53. }
  54. #endif
  55. auth.signInAnonymously { result, error in
  56. }
  57. auth.signIn(withCustomToken: "abc") { result, error in
  58. }
  59. auth.createUser(withEmail: "email", password: "password") { result, error in
  60. }
  61. auth.confirmPasswordReset(withCode: "code", newPassword: "password") { error in
  62. }
  63. auth.checkActionCode("abc") { codeInfo, error in
  64. }
  65. auth.verifyPasswordResetCode("code") { email, error in
  66. }
  67. auth.applyActionCode("code") { error in
  68. }
  69. auth.sendPasswordReset(withEmail: "email") { error in
  70. }
  71. let actionCodeSettings = ActionCodeSettings()
  72. auth.sendPasswordReset(withEmail: "email", actionCodeSettings: actionCodeSettings) { error in
  73. }
  74. auth.sendSignInLink(toEmail: "email", actionCodeSettings: actionCodeSettings) { error in
  75. }
  76. try auth.signOut()
  77. auth.isSignIn(withEmailLink: "link")
  78. let handle = auth.addStateDidChangeListener { auth, user in
  79. }
  80. auth.removeStateDidChangeListener(handle)
  81. auth.addIDTokenDidChangeListener { auth, user in
  82. }
  83. auth.removeIDTokenDidChangeListener(handle)
  84. auth.useAppLanguage()
  85. auth.useEmulator(withHost: "myHost", port: 123)
  86. #if !os(macOS)
  87. auth.canHandle(URL(fileURLWithPath: "/my/path"))
  88. auth.setAPNSToken(Data(), type: AuthAPNSTokenType(rawValue: 2)!)
  89. auth.canHandleNotification([:])
  90. #endif
  91. try auth.useUserAccessGroup("abc")
  92. let nilUser = try auth.getStoredUser(forAccessGroup: "def")
  93. // If nilUser is not optional, this will raise a compiler error.
  94. // This condition does not need to execute, and may not if prior
  95. // functions throw.
  96. if let _ = nilUser {
  97. XCTAssert(true)
  98. }
  99. }
  100. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  101. func FIRAuth_hAsync() async throws {
  102. let auth = FirebaseAuth.Auth.auth()
  103. let user = auth.currentUser!
  104. try await auth.updateCurrentUser(user)
  105. _ = try await auth.fetchSignInMethods(forEmail: "abc@abc.com")
  106. _ = try await auth.signIn(withEmail: "abc@abc.com", password: "password")
  107. _ = try await auth.signIn(withEmail: "abc@abc.com", link: "link")
  108. let provider = OAuthProvider(providerID: "abc")
  109. #if !os(macOS)
  110. let credential = try await provider.credential(with: nil)
  111. _ = try await auth.signIn(with: OAuthProvider(providerID: "abc"), uiDelegate: nil)
  112. _ = try await auth.signIn(with: credential)
  113. #endif
  114. _ = try await auth.signInAnonymously()
  115. _ = try await auth.signIn(withCustomToken: "abc")
  116. _ = try await auth.createUser(withEmail: "email", password: "password")
  117. _ = try await auth.confirmPasswordReset(withCode: "code", newPassword: "password")
  118. _ = try await auth.checkActionCode("abc")
  119. _ = try await auth.verifyPasswordResetCode("code")
  120. _ = try await auth.applyActionCode("code")
  121. _ = try await auth.sendPasswordReset(withEmail: "email")
  122. let actionCodeSettings = ActionCodeSettings()
  123. _ = try await auth.sendPasswordReset(
  124. withEmail: "email",
  125. actionCodeSettings: actionCodeSettings
  126. )
  127. _ = try await auth.sendSignInLink(toEmail: "email", actionCodeSettings: actionCodeSettings)
  128. }
  129. #if !os(macOS)
  130. func FIRAuthAPNSTokenType_h() {
  131. _ = AuthAPNSTokenType.unknown
  132. _ = AuthAPNSTokenType.sandbox
  133. _ = AuthAPNSTokenType.prod
  134. }
  135. #endif
  136. func FIRAuthErrors_h() {
  137. _ = AuthErrorCode.invalidCustomToken
  138. _ = AuthErrorCode.customTokenMismatch
  139. _ = AuthErrorCode.invalidCredential
  140. _ = AuthErrorCode.userDisabled
  141. _ = AuthErrorCode.operationNotAllowed
  142. _ = AuthErrorCode.emailAlreadyInUse
  143. _ = AuthErrorCode.invalidEmail
  144. _ = AuthErrorCode.wrongPassword
  145. _ = AuthErrorCode.tooManyRequests
  146. _ = AuthErrorCode.userNotFound
  147. _ = AuthErrorCode.accountExistsWithDifferentCredential
  148. _ = AuthErrorCode.requiresRecentLogin
  149. _ = AuthErrorCode.providerAlreadyLinked
  150. _ = AuthErrorCode.noSuchProvider
  151. _ = AuthErrorCode.invalidUserToken
  152. _ = AuthErrorCode.networkError
  153. _ = AuthErrorCode.userTokenExpired
  154. _ = AuthErrorCode.invalidAPIKey
  155. _ = AuthErrorCode.userMismatch
  156. _ = AuthErrorCode.credentialAlreadyInUse
  157. _ = AuthErrorCode.weakPassword
  158. _ = AuthErrorCode.appNotAuthorized
  159. _ = AuthErrorCode.expiredActionCode
  160. _ = AuthErrorCode.invalidActionCode
  161. _ = AuthErrorCode.invalidMessagePayload
  162. _ = AuthErrorCode.invalidSender
  163. _ = AuthErrorCode.invalidRecipientEmail
  164. _ = AuthErrorCode.missingEmail
  165. _ = AuthErrorCode.missingIosBundleID
  166. _ = AuthErrorCode.missingAndroidPackageName
  167. _ = AuthErrorCode.unauthorizedDomain
  168. _ = AuthErrorCode.invalidContinueURI
  169. _ = AuthErrorCode.missingContinueURI
  170. _ = AuthErrorCode.missingPhoneNumber
  171. _ = AuthErrorCode.invalidPhoneNumber
  172. _ = AuthErrorCode.missingVerificationCode
  173. _ = AuthErrorCode.invalidVerificationCode
  174. _ = AuthErrorCode.missingVerificationID
  175. _ = AuthErrorCode.invalidVerificationID
  176. _ = AuthErrorCode.missingAppCredential
  177. _ = AuthErrorCode.invalidAppCredential
  178. _ = AuthErrorCode.sessionExpired
  179. _ = AuthErrorCode.quotaExceeded
  180. _ = AuthErrorCode.missingAppToken
  181. _ = AuthErrorCode.notificationNotForwarded
  182. _ = AuthErrorCode.appNotVerified
  183. _ = AuthErrorCode.captchaCheckFailed
  184. _ = AuthErrorCode.webContextAlreadyPresented
  185. _ = AuthErrorCode.webContextCancelled
  186. _ = AuthErrorCode.appVerificationUserInteractionFailure
  187. _ = AuthErrorCode.invalidClientID
  188. _ = AuthErrorCode.webNetworkRequestFailed
  189. _ = AuthErrorCode.webInternalError
  190. _ = AuthErrorCode.webSignInUserInteractionFailure
  191. _ = AuthErrorCode.localPlayerNotAuthenticated
  192. _ = AuthErrorCode.nullUser
  193. _ = AuthErrorCode.dynamicLinkNotActivated
  194. _ = AuthErrorCode.invalidProviderID
  195. _ = AuthErrorCode.tenantIDMismatch
  196. _ = AuthErrorCode.unsupportedTenantOperation
  197. _ = AuthErrorCode.invalidDynamicLinkDomain
  198. _ = AuthErrorCode.rejectedCredential
  199. _ = AuthErrorCode.gameKitNotLinked
  200. _ = AuthErrorCode.secondFactorRequired
  201. _ = AuthErrorCode.missingMultiFactorSession
  202. _ = AuthErrorCode.missingMultiFactorInfo
  203. _ = AuthErrorCode.invalidMultiFactorSession
  204. _ = AuthErrorCode.multiFactorInfoNotFound
  205. _ = AuthErrorCode.adminRestrictedOperation
  206. _ = AuthErrorCode.unverifiedEmail
  207. _ = AuthErrorCode.secondFactorAlreadyEnrolled
  208. _ = AuthErrorCode.maximumSecondFactorCountExceeded
  209. _ = AuthErrorCode.unsupportedFirstFactor
  210. _ = AuthErrorCode.emailChangeNeedsVerification
  211. _ = AuthErrorCode.missingOrInvalidNonce
  212. _ = AuthErrorCode.missingClientIdentifier
  213. _ = AuthErrorCode.keychainError
  214. _ = AuthErrorCode.internalError
  215. _ = AuthErrorCode.malformedJWT
  216. }
  217. #if !os(macOS)
  218. func FIRAuthUIDelegate_h() {
  219. class AuthUIImpl: NSObject, AuthUIDelegate {
  220. func present(_ viewControllerToPresent: UIViewController, animated flag: Bool,
  221. completion: (() -> Void)? = nil) {}
  222. func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {}
  223. }
  224. let obj = AuthUIImpl()
  225. obj.present(UIViewController(), animated: true) {}
  226. obj.dismiss(animated: false) {}
  227. }
  228. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  229. func FIRAuthUIDelegate_hAsync() async {
  230. class AuthUIImpl: NSObject, AuthUIDelegate {
  231. func present(_ viewControllerToPresent: UIViewController, animated flag: Bool) async {}
  232. func dismiss(animated flag: Bool) async {}
  233. }
  234. let obj = AuthUIImpl()
  235. await obj.present(UIViewController(), animated: true)
  236. await obj.dismiss(animated: false)
  237. }
  238. #endif
  239. func FIREmailAuthProvider_h() {
  240. _ = EmailAuthProvider.credential(withEmail: "e@email.com", password: "password")
  241. _ = EmailAuthProvider.credential(withEmail: "e@email.com", link: "link")
  242. }
  243. func FIRFacebookAuthProvider_h() {
  244. _ = FacebookAuthProvider.credential(withAccessToken: "token")
  245. }
  246. #if !os(macOS)
  247. func FIRFedederatedAuthProvider_h() {
  248. class FederatedAuthImplementation: NSObject, FederatedAuthProvider {
  249. func getCredentialWith(_ UIDelegate: AuthUIDelegate?,
  250. completion: ((AuthCredential?, Error?) -> Void)? = nil) {}
  251. }
  252. let obj = FederatedAuthImplementation()
  253. obj.getCredentialWith(nil) { _, _ in
  254. }
  255. }
  256. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  257. func FIRFedederatedAuthProvider_hAsync() async throws {
  258. class FederatedAuthImplementation: NSObject, FederatedAuthProvider {
  259. func credential(with UIDelegate: AuthUIDelegate?) async throws -> AuthCredential {
  260. return FacebookAuthProvider.credential(withAccessToken: "token")
  261. }
  262. }
  263. let obj = FederatedAuthImplementation()
  264. try await _ = obj.credential(with: nil)
  265. }
  266. #endif
  267. func FIRGameCenterAuthProvider_h() {
  268. GameCenterAuthProvider.getCredential { _, _ in
  269. }
  270. }
  271. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  272. func FIRGameCenterAuthProvider_hAsync() async throws {
  273. _ = try await GameCenterAuthProvider.getCredential()
  274. }
  275. func FIRGitHubAuthProvider_h() {
  276. _ = GitHubAuthProvider.credential(withToken: "token")
  277. }
  278. func FIRGoogleAuthProvider_h() {
  279. _ = GoogleAuthProvider.credential(withIDToken: "token", accessToken: "aToken")
  280. }
  281. #if os(iOS)
  282. func FIRMultiFactor_h() {
  283. let obj = MultiFactor()
  284. obj.getSessionWithCompletion { _, _ in
  285. }
  286. obj.enroll(with: MultiFactorAssertion(), displayName: "name") { _ in
  287. }
  288. obj.unenroll(with: MultiFactorInfo()) { _ in
  289. }
  290. obj.unenroll(withFactorUID: "uid") { _ in
  291. }
  292. }
  293. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  294. func FIRMultiFactor_hAsync() async throws {
  295. let obj = MultiFactor()
  296. try await obj.session()
  297. try await obj.enroll(with: MultiFactorAssertion(), displayName: "name")
  298. try await obj.unenroll(with: MultiFactorInfo())
  299. try await obj.unenroll(withFactorUID: "uid")
  300. }
  301. func FIRMultiFactorResolver_h() {
  302. let obj = MultiFactorResolver()
  303. obj.resolveSignIn(with: MultiFactorAssertion()) { _, _ in
  304. }
  305. }
  306. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  307. func FIRMultiFactorResolver_hAsync() async throws {
  308. let obj = MultiFactorResolver()
  309. try await obj.resolveSignIn(with: MultiFactorAssertion())
  310. }
  311. #endif
  312. func FIROAuthProvider_h() {
  313. let provider = OAuthProvider(providerID: "id", auth: FirebaseAuth.Auth.auth())
  314. _ = provider.providerID
  315. #if os(iOS)
  316. _ = OAuthProvider.credential(withProviderID: "id", idToken: "idToden", accessToken: "token")
  317. _ = OAuthProvider.credential(withProviderID: "id", accessToken: "token")
  318. _ = OAuthProvider.credential(withProviderID: "id", idToken: "idToken", rawNonce: "nonce",
  319. accessToken: "token")
  320. _ = OAuthProvider.credential(withProviderID: "id", idToken: "idToken", rawNonce: "nonce")
  321. provider.getCredentialWith(provider as? AuthUIDelegate) { credential, error in
  322. }
  323. #endif
  324. }
  325. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  326. func FIROAuthProvider_h() async throws {
  327. let provider = OAuthProvider(providerID: GoogleAuthProvider.id, auth: FirebaseAuth.Auth.auth())
  328. #if os(iOS)
  329. provider.getCredentialWith(provider as? AuthUIDelegate) { credential, error in
  330. }
  331. try await provider.credential(with: provider as? AuthUIDelegate)
  332. #endif
  333. }
  334. #if os(iOS)
  335. func FIRPhoneAuthProvider_h() {
  336. _ = PhoneAuthProvider.provider()
  337. let provider = PhoneAuthProvider.provider(auth: FirebaseAuth.Auth.auth())
  338. provider.verifyPhoneNumber("123", uiDelegate: nil) { _, _ in
  339. }
  340. provider.verifyPhoneNumber("123", uiDelegate: nil, multiFactorSession: nil) { _, _ in
  341. }
  342. provider.verifyPhoneNumber(
  343. with: PhoneMultiFactorInfo(),
  344. uiDelegate: nil,
  345. multiFactorSession: nil
  346. ) { _, _ in
  347. }
  348. provider.verifyPhoneNumber("123", uiDelegate: nil, multiFactorSession: nil) { _, _ in
  349. }
  350. provider.credential(withVerificationID: "id", verificationCode: "code")
  351. }
  352. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  353. func FIRPhoneAuthProvider_hAsync() async throws {
  354. _ = PhoneAuthProvider.provider()
  355. let provider = PhoneAuthProvider.provider(auth: FirebaseAuth.Auth.auth())
  356. try await provider.verifyPhoneNumber("123", uiDelegate: nil)
  357. try await provider.verifyPhoneNumber("123", uiDelegate: nil, multiFactorSession: nil)
  358. try await provider.verifyPhoneNumber(with: PhoneMultiFactorInfo(), uiDelegate: nil,
  359. multiFactorSession: nil)
  360. try await provider.verifyPhoneNumber("123", uiDelegate: nil, multiFactorSession: nil)
  361. }
  362. func FIRPhoneMultiFactorGenerator_h() {
  363. let credential = PhoneAuthProvider.provider().credential(withVerificationID: "id",
  364. verificationCode: "code")
  365. PhoneMultiFactorGenerator.assertion(with: credential)
  366. }
  367. #endif
  368. func FIRTOTPSecret_h() {
  369. let obj = TOTPSecret()
  370. obj.sharedSecretKey()
  371. obj.generateQRCodeURL(withAccountName: "name", issuer: "issuer")
  372. obj.openInOTPApp(withQRCodeURL: "url")
  373. }
  374. func FIRTOTPMultiFactorGenerator_h() {
  375. TOTPMultiFactorGenerator.generateSecret(with: MultiFactorSession()) { _, _ in
  376. }
  377. TOTPMultiFactorGenerator.assertionForEnrollment(with: TOTPSecret(), oneTimePassword: "code")
  378. TOTPMultiFactorGenerator.assertionForSignIn(withEnrollmentID: "id",
  379. oneTimePassword: "code")
  380. }
  381. #if compiler(>=5.5.2) && canImport(_Concurrency)
  382. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  383. func FIRTOTPMultiFactorGenerator_hAsync() async throws {
  384. try await TOTPMultiFactorGenerator.generateSecret(with: MultiFactorSession())
  385. }
  386. #endif
  387. func FIRTwitterAuthProvider_h() {
  388. _ = TwitterAuthProvider.credential(withToken: "token", secret: "secret")
  389. }
  390. func FIRUser_h() {
  391. let auth = FirebaseAuth.Auth.auth()
  392. let user = auth.currentUser!
  393. let credential = GoogleAuthProvider.credential(withIDToken: "token", accessToken: "aToken")
  394. user.updateEmail(to: "email") { _ in
  395. }
  396. user.updatePassword(to: "password") { _ in
  397. }
  398. let changeRequest = user.createProfileChangeRequest()
  399. user.reload { _ in
  400. }
  401. user.reauthenticate(with: credential) { _, _ in
  402. }
  403. #if os(iOS)
  404. user.updatePhoneNumber(credential) { _ in
  405. }
  406. let provider = PhoneAuthProvider.provider(auth: FirebaseAuth.Auth.auth())
  407. user.reauthenticate(with: provider as! FederatedAuthProvider, uiDelegate: nil)
  408. user.link(with: provider as! FederatedAuthProvider, uiDelegate: nil) { _, _ in
  409. }
  410. #endif
  411. user.getIDTokenResult { _, _ in
  412. }
  413. user.getIDTokenResult(forcingRefresh: true) { _, _ in
  414. }
  415. user.getIDTokenResult { _, _ in
  416. }
  417. user.getIDTokenForcingRefresh(true) { _, _ in
  418. }
  419. user.link(with: credential) { _, _ in
  420. }
  421. user.unlink(fromProvider: "abc") { _, _ in
  422. }
  423. user.sendEmailVerification { _ in
  424. }
  425. user.sendEmailVerification(with: ActionCodeSettings()) { _ in
  426. }
  427. user.delete { _ in
  428. }
  429. user.sendEmailVerification(beforeUpdatingEmail: "email") { _ in
  430. }
  431. user.sendEmailVerification(
  432. beforeUpdatingEmail: "email",
  433. actionCodeSettings: ActionCodeSettings()
  434. ) { _ in
  435. }
  436. changeRequest.commitChanges { _ in
  437. }
  438. }
  439. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  440. func FIRUser_hAsync() async throws {
  441. let auth = FirebaseAuth.Auth.auth()
  442. let user = auth.currentUser!
  443. let credential = GoogleAuthProvider.credential(withIDToken: "token", accessToken: "aToken")
  444. try await user.updateEmail(to: "email")
  445. try await user.updatePassword(to: "password")
  446. let changeRequest = user.createProfileChangeRequest()
  447. try await user.reload()
  448. try await user.reauthenticate(with: credential)
  449. #if os(iOS)
  450. try await user.updatePhoneNumber(credential)
  451. let provider = PhoneAuthProvider.provider(auth: FirebaseAuth.Auth.auth())
  452. try await user.reauthenticate(with: provider as! FederatedAuthProvider, uiDelegate: nil)
  453. try await user.link(with: provider as! FederatedAuthProvider, uiDelegate: nil)
  454. #endif
  455. try await user.getIDTokenResult()
  456. try await user.getIDTokenResult(forcingRefresh: true)
  457. try await user.getIDTokenResult()
  458. try await user.link(with: credential)
  459. try await user.unlink(fromProvider: "abc")
  460. try await user.sendEmailVerification()
  461. try await user.sendEmailVerification(with: ActionCodeSettings())
  462. try await user.delete()
  463. try await user.sendEmailVerification(beforeUpdatingEmail: "email")
  464. try await user.sendEmailVerification(
  465. beforeUpdatingEmail: "email",
  466. actionCodeSettings: ActionCodeSettings()
  467. )
  468. try await changeRequest.commitChanges()
  469. }
  470. }