Files
firebase-ios-sdk/FirebaseAuth/Sources/Swift/User/UserProfileChangeRequest.swift
T
Nick Cookeandgemini-code-assist[bot] dc18b7f5b9 refactor(global): cleanup redundant availability checks and update sample apps audit (#16143)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-04-30 18:48:30 -04:00

127 lines
4.0 KiB
Swift

// 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
/// Represents an object capable of updating a user's profile data.
///
/// Properties are marked as being part of a profile update when they are set. Setting a
/// property value to nil is not the same as leaving the property unassigned.
@objc(FIRUserProfileChangeRequest) open class UserProfileChangeRequest: NSObject {
/// The name of the user.
@objc open var displayName: String? {
get { return _displayName }
set(newDisplayName) {
kAuthGlobalWorkQueue.async {
if self.consumed {
fatalError("Internal Auth Error: Invalid call to setDisplayName after commitChanges.")
}
self.displayNameWasSet = true
self._displayName = newDisplayName
}
}
}
private var _displayName: String?
/// The URL of the user's profile photo.
@objc open var photoURL: URL? {
get { return _photoURL }
set(newPhotoURL) {
kAuthGlobalWorkQueue.async {
if self.consumed {
fatalError("Internal Auth Error: Invalid call to setPhotoURL after commitChanges.")
}
self.photoURLWasSet = true
self._photoURL = newPhotoURL
}
}
}
private var _photoURL: URL?
/// Commits any pending changes.
///
/// Invoked asynchronously on the main thread in the future.
///
/// This method should only be called once.Once called, property values should not be changed.
/// - Parameter completion: Optionally; the block invoked when the user profile change has been
/// applied.
@objc open func commitChanges(completion: ((Error?) -> Void)? = nil) {
kAuthGlobalWorkQueue.async {
if self.consumed {
fatalError("Internal Auth Error: commitChanges should only be called once.")
}
self.consumed = true
// Return fast if there is nothing to update:
if !self.photoURLWasSet, !self.displayNameWasSet {
User.callInMainThreadWithError(callback: completion, error: nil)
return
}
let displayName = self.displayName
let displayNameWasSet = self.displayNameWasSet
let photoURL = self.photoURL
let photoURLWasSet = self.photoURLWasSet
self.user.executeUserUpdateWithChanges(changeBlock: { user, request in
if photoURLWasSet {
request.photoURL = photoURL
}
if displayNameWasSet {
request.displayName = displayName
}
}) { error in
if let error {
User.callInMainThreadWithError(callback: completion, error: error)
return
}
if displayNameWasSet {
self.user.displayName = displayName
}
if photoURLWasSet {
self.user.photoURL = photoURL
}
if let error = self.user.updateKeychain() {
User.callInMainThreadWithError(callback: completion, error: error)
}
User.callInMainThreadWithError(callback: completion, error: nil)
}
}
}
/// Commits any pending changes.
///
/// This method should only be called once. Once called, property values should not be changed.
open func commitChanges() async throws {
return try await withCheckedThrowingContinuation { continuation in
self.commitChanges { error in
if let error {
continuation.resume(throwing: error)
} else {
continuation.resume()
}
}
}
}
init(_ user: User) {
self.user = user
}
private let user: User
private var consumed = false
private var displayNameWasSet = false
private var photoURLWasSet = false
}