Skip to content

Commit

Permalink
Ensure name is updated after anonymous account linking (#36)
Browse files Browse the repository at this point in the history
# Ensure name is updated after anonymous account linking

## ♻️ Current situation & Problem
As described in #35, the displayName is not updated in the signup code
path that handles linking signup credentials with an existing anonymous
account.
This PR fixes this issue by updating the display name of the anonymous
account if the signup request provides a display name.


## ⚙️ Release Notes 
* Fixed an issue where the displayName was not updated when signing in
by linking against an anonymous user account.


## 📚 Documentation
--


## ✅ Testing
A regression test was added that verifies this behavior.


## 📝 Code of Conduct & Contributing Guidelines 

By submitting creating this pull request, you agree to follow our [Code
of
Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md)
and [Contributing
Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md):
- [x] I agree to follow the [Code of
Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md)
and [Contributing
Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md).
  • Loading branch information
Supereg authored Jun 11, 2024
1 parent f05c859 commit 00ff0db
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,7 @@ extension FirebaseAccountService {
}

if let name = modifications.modifiedDetails.name {
Self.logger.debug("Creating change request for updated display name.")
let changeRequest = currentUser.createProfileChangeRequest()
changeRequest.displayName = name.formatted(.name(style: .long))
try await changeRequest.commitChanges()
try await updateDisplayName(of: currentUser, name)
}

// None of the above requests will trigger our state change listener, therefore, we just call it manually.
Expand All @@ -129,4 +126,11 @@ extension FirebaseAccountService {
throw FirebaseAccountError.unknown(.internalError)
}
}

func updateDisplayName(of user: User, _ name: PersonNameComponents) async throws {
Self.logger.debug("Creating change request for updated display name.")
let changeRequest = user.createProfileChangeRequest()
changeRequest.displayName = name.formatted(.name(style: .long))
try await changeRequest.commitChanges()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,11 @@ actor FirebaseEmailPasswordAccountService: UserIdPasswordAccountService, Firebas
Self.logger.debug("Linking email-password credentials with current anonymous user account ...")
let result = try await currentUser.link(with: credential)

try await context.notifyUserSignIn(user: currentUser, for: self, isNewUser: true)
if let displayName = signupDetails.name {
try await updateDisplayName(of: result.user, displayName)
}

try await context.notifyUserSignIn(user: result.user, for: self)

return
}
Expand All @@ -105,10 +109,7 @@ actor FirebaseEmailPasswordAccountService: UserIdPasswordAccountService, Firebas
try await authResult.user.sendEmailVerification()

if let displayName = signupDetails.name {
Self.logger.debug("Creating change request for display name.")
let changeRequest = authResult.user.createProfileChangeRequest()
changeRequest.displayName = displayName.formatted(.name(style: .medium))
try await changeRequest.commitChanges()
try await updateDisplayName(of: authResult.user, displayName)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// SPDX-License-Identifier: MIT
//

import FirebaseAuth
@preconcurrency import FirebaseAuth
import Spezi
import SpeziAccount
import SpeziFirebaseAccount
Expand All @@ -24,9 +24,18 @@ struct FirebaseAccountTestsView: View {
@State var showSetup = false
@State var showOverview = false
@State var isEditing = false


@State var uiUpdates: Int = 0

var body: some View {
List {
if uiUpdates > 0, // register to UI updates
let user = Auth.auth().currentUser,
user.isAnonymous {
ListRow("User") {
Text("Anonymous")
}
}
if let details = account.details {
HStack {
UserProfileView(name: details.name ?? .init(givenName: "NOT FOUND"))
Expand All @@ -44,6 +53,15 @@ struct FirebaseAccountTestsView: View {
Button("Account Overview") {
showOverview = true
}
if !account.signedIn {
AsyncButton("Login Anonymously", state: $viewState) {
if Auth.auth().currentUser != nil {
try Auth.auth().signOut()
}
try await Auth.auth().signInAnonymously()
uiUpdates += 1
}
}
}
.sheet(isPresented: $showSetup) {
NavigationStack {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// SPDX-License-Identifier: MIT
//

import FirebaseStorage
@preconcurrency import FirebaseStorage
import PDFKit
import SpeziViews
import SwiftUI
Expand Down Expand Up @@ -35,7 +35,9 @@ struct FirebaseStorageTestsView: View {
let ref = Storage.storage().reference().child("test.txt")
let metadata = StorageMetadata()
metadata.contentType = "text/plain"
_ = try await ref.putDataAsync("Hello World!".data(using: .utf8) ?? .init(), metadata: metadata)
_ = try await ref.putDataAsync("Hello World!".data(using: .utf8) ?? .init(), metadata: metadata) { @Sendable _ in
// silence warning
}
viewState = .idle
} catch {
viewState = .error(AnyLocalizedError(error: error))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// SPDX-License-Identifier: MIT
//

import FirebaseFirestore
@preconcurrency import FirebaseFirestore
import Spezi
import SpeziFirestore
import SpeziViews
Expand Down
25 changes: 25 additions & 0 deletions Tests/UITests/TestAppUITests/FirebaseAccountTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,30 @@ final class FirebaseAccountTests: XCTestCase { // swiftlint:disable:this type_bo

app.tap() // that triggers the interruption monitor closure
}

func testSignupAccountLinking() throws {
let app = XCUIApplication()
app.launchArguments = ["--account-storage"]
app.launch()

XCTAssert(app.buttons["FirebaseAccount"].waitForExistence(timeout: 10.0))
app.buttons["FirebaseAccount"].tap()

if app.buttons["Logout"].waitForExistence(timeout: 3.0) && app.buttons["Logout"].isHittable {
app.buttons["Logout"].tap()
}

XCTAssertTrue(app.buttons["Login Anonymously"].waitForExistence(timeout: 2.0))
app.buttons["Login Anonymously"].tap()

XCTAssertTrue(app.staticTexts["User, Anonymous"].waitForExistence(timeout: 5.0))

try app.signup(username: "[email protected]", password: "TestPassword2", givenName: "Leland", familyName: "Stanford", biography: "Bio")

app.buttons["Account Overview"].tap()
XCTAssert(app.staticTexts["Leland Stanford"].waitForExistence(timeout: 2.0))
XCTAssert(app.staticTexts["Biography, Bio"].exists)
}
}


Expand Down Expand Up @@ -494,3 +518,4 @@ extension XCUIApplication {
buttons["Close"].tap()
}
}
// swiftlint:disable:this file_length
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,35 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "df308b8b46607675f2b9ec8e569109008f9155ce",
"version" : "1.2022062300.1"
"revision" : "748c7837511d0e6a507737353af268484e1745e2",
"version" : "1.2024011601.1"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "3e464dad87dad2d29bb29a97836789bf0f8f67d2",
"version" : "10.18.1"
"revision" : "076b241a625e25eac22f8849be256dfb960fcdfe",
"version" : "10.19.1"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk",
"state" : {
"revision" : "be49849dcba96f2b5ee550d4eceb2c0fa27dade4",
"version" : "10.22.1"
"revision" : "8bcaf973b1d84e119b7c7c119abad72ed460979f",
"version" : "10.27.0"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "482cfa4e5880f0a29f66ecfd60c5a62af28bd1f0",
"version" : "10.22.1"
"revision" : "70df02431e216bed98dd461e0c4665889245ba70",
"version" : "10.27.0"
}
},
{
Expand All @@ -50,26 +50,26 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "26c898aed8bed13b8a63057ee26500abbbcb8d55",
"version" : "7.13.1"
"revision" : "57a1d307f42df690fdef2637f3e5b776da02aad6",
"version" : "7.13.3"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "ea4cb5cc0c39c732b85386263116d2e2fdbbdc61",
"version" : "1.49.2"
"revision" : "e9fad491d0673bdda7063a0341fb6b47a30c5359",
"version" : "1.62.2"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "76135c9f4e1ac85459d5fec61b6f76ac47ab3a4c",
"version" : "3.3.1"
"revision" : "0382ca27f22fb3494cf657d8dc356dc282cd1193",
"version" : "3.4.1"
}
},
{
Expand All @@ -86,8 +86,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "43aaef65e0c665daadf848761d560e446d350d3d",
"version" : "1.22.4"
"revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
"version" : "1.22.5"
}
},
{
Expand All @@ -113,17 +113,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/StanfordSpezi/Spezi",
"state" : {
"revision" : "c43e4fa3d3938a847de2b677091a34ddaea5bc76",
"version" : "1.2.3"
"revision" : "734f90c19422a4196762b0e1dd055471066e89ee",
"version" : "1.3.0"
}
},
{
"identity" : "speziaccount",
"kind" : "remoteSourceControl",
"location" : "https://github.com/StanfordSpezi/SpeziAccount",
"state" : {
"revision" : "cb9441e5fe9ca31a17be2507d03817a080e63e9d",
"version" : "1.2.2"
"revision" : "2de07209430fe7b13c44790eab948b30482fcb9d",
"version" : "1.2.4"
}
},
{
Expand Down Expand Up @@ -158,17 +158,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb",
"version" : "1.1.0"
"revision" : "ee97538f5b81ae89698fd95938896dec5217b148",
"version" : "1.1.1"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "65e8f29b2d63c4e38e736b25c27b83e012159be8",
"version" : "1.25.2"
"revision" : "9f0c76544701845ad98716f3f6a774a892152bcb",
"version" : "1.26.0"
}
},
{
Expand Down

0 comments on commit 00ff0db

Please sign in to comment.