Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using Sign In with Apple to create an account displayName value of the auth user is not being set #815

Closed
KrisConrad opened this issue Dec 16, 2019 · 27 comments
Assignees

Comments

@KrisConrad
Copy link

Step 1: Are you in the right place?

  • For issues or feature requests related to the code in this repository file a GitHub issue.
  • For general technical questions, post a question on StackOverflow tagged appropriately.
  • For general Firebase discussion, use the firebase-talk google group
  • For help troubleshooting your application that does not fall under one of the above categories, reach out to the personalized Firebase support channel

Step 2: Describe your environment

  • Objective C or Swift: Swift
  • iOS version: 13
  • Firebase SDK version: 6.14
  • FirebaseUI version: 8.4
  • CocoaPods Version: 1.8.4

Step 3: Describe the problem:

Steps to reproduce:

  1. Sign in using Sign In With Apple for the first time

Observed Results:

  • What happened?

Auth.auth().currentUser?.displayName in nil

Expected Results:

  • What did you expect to happen?

For Auth.auth().currentUser?.displayName to be set to the fullName value of the ASAuthorizationAppleIDCredential passed into the authorizationController:didCompleteWithAuthorization method of the ASAuthorizationControllerDelegate

@morganchen12
Copy link
Contributor

Closing this in favor of firebase/firebase-ios-sdk#4393. We'll continue updating the issue there.

Please let me know if this is actually a different issue.

@KrisConrad
Copy link
Author

KrisConrad commented Dec 17, 2019

@morganchen12 After looking through that issue, I think this is a related, but separate issue.

Unless I'm misunderstanding, the Firebase SDK isn't setting the displayName on the Auth().currentUser because the name is not provided in the ID Token. It looks like the proposed solution in firebase/firebase-ios-sdk#4393 is to update the documentation to inform developers that they will have to update the displayName value in a separate call.

If this is the case it seems like it would then be the responsibility of the FirebaseUI SDK to implement that second call.

let changeRequest = Auth.auth().currentUser?.createProfileChangeRequest()
changeRequest?.displayName = displayName
changeRequest?.commitChanges { (error) in
  // ...
}

@morganchen12 morganchen12 reopened this Dec 17, 2019
@morganchen12
Copy link
Contributor

Good point, I'll address that in this library.

@langhoangal
Copy link

Hi @KrisConrad, could you help me on this,

When using Firebase Auth UI, what all i need to do are:

  • set provider (which is has FUIOAuth.appleAuthProvider())
  • create authViewController
  • call present(authViewController!, animated: true, completion: nil) at final step to open signin screen.

And, there is a protocol named FUIAuthDelegate to get the callback also. What i want to known is how can I deal with didCompleteWithAuthorization in this case. I don't see the connection between them.

@morganchen12
Copy link
Contributor

Hey @langhoangal, the didCompleteWithAuthorization method will be called if sign in with apple is successful. You should be able to retrieve the user from that callback.

@nex-derek
Copy link

Good point, I'll address that in this library.

@morganchen12 Hi, wondering if there an ETA to get it done? Thanks!

@morganchen12
Copy link
Contributor

morganchen12 commented Mar 3, 2020

No, no ETA. :(

@IchordeDionysos
Copy link

@morganchen12 Apple updated their guidelines and they require Sign-In with Apple starting April 30, 2020 [1].

Are you intending to solve this issue before that date or do still have no ETA? 🤔🙂

[1] https://9to5mac.com/2020/03/04/apple-now-allows-push-notification-advertising-updates-dating-app-review-guidelines-and-more/

@morganchen12
Copy link
Contributor

I'll aim to solve it before then.

@NaturalLam
Copy link

@morganchen12 , any update on this?

@NaturalLam
Copy link

@morganchen12 , do you still have target to solve this before Apple's deadline?

@morganchen12
Copy link
Contributor

Hey, unfortunately I have not been able to resolve this before the deadline. You can work around this by prompting your user for a name or fetching the name via Firebase Auth.

@IchordeDionysos
Copy link

@morganchen12 Deadline has been moved to June 30.

https://developer.apple.com/news/?id=03262020b

@NaturalLam
Copy link

@morganchen12 Apple already started enforcing this, do we have plan to fix?

@iTarek
Copy link

iTarek commented Jul 16, 2020

I had to ask user for display name after sign in with apple, till this get fixed

@iTarek
Copy link

iTarek commented Jul 16, 2020

Hey, unfortunately I have not been able to resolve this before the deadline. You can work around this by prompting your user for a name or fetching the name via Firebase Auth.

You can not even fetch the name via Firebase Auth, it's NIL

@KrisConrad
Copy link
Author

This has become more important, Today we got a rejection for our app (see below). I now have a release with a deadline of Monday and not enough time to rip out the FirebaseUI SDK and rewrite our log in flow so we don't have to ask the user for their name:

Guideline 5.1.1 - Legal - Privacy - Data Collection and Storage

We noticed that after users authenticate their account with Sign in with Apple, they are required to take additional steps before they can access content and features in your app. Specifically:

  • Your app requires users to provide their name and/or email address after using Sign in with Apple.

Sign in with Apple is designed to be a self-contained, all-in-one login system. With security features like built-in two-factor authentication, you can remove additional sign-up steps so users can focus on your app's content and features.

@yuchenshi
Copy link
Member

@rosalyntan Would you mind looking into this?

@KrisConrad
Copy link
Author

For anyone else who is in desperate need of getting their app through Apple Review and is in need of a (hopefully temporary) solution I'll share what I'm doing.

First I wrote an extension for FUIOAuth to swizzle the delegate method Apple calls when a user successfully signs in with Apple. The auth process with Firebase hasn't finished at the time this method is called so I look for the full name of the user and save it to UserDefaults.

import AuthenticationServices

@available(iOS 13.0, *)
extension FUIOAuth {
    static func swizzleAppleAuthCompletion() {
        let instance = FUIOAuth.appleAuthProvider()
        let originalSelector = NSSelectorFromString("authorizationController:didCompleteWithAuthorization:")
        let swizzledSelector = #selector(swizzledAuthorizationController(controller:didCompleteWithAuthorization:))
        guard let originalMethod = class_getInstanceMethod(instance.classForCoder, originalSelector),
              let swizzledMethod = class_getInstanceMethod(instance.classForCoder, swizzledSelector) else { return }
        method_exchangeImplementations(originalMethod, swizzledMethod)
    }

    @objc func swizzledAuthorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        if let nameComponents = (authorization.credential as? ASAuthorizationAppleIDCredential)?.fullName {
            let nameFormatter = PersonNameComponentsFormatter()
            let displayName = nameFormatter.string(from: nameComponents)
            UserDefaults.standard.setValue(displayName, forKey: "displayName")
            UserDefaults.standard.synchronize()
        }
        swizzledAuthorizationController(controller: controller, didCompleteWithAuthorization: authorization)
    }
}

Then elsewhere, when setting up the defaultAuthUI I call the function to swizzle the methods above:

        var providers: [FUIAuthProvider] = []

        if #available(iOS 13.0, *) {
            providers.append(FUIOAuth.properAppleAuthProvider)
            FUIOAuth.swizzleAppleAuthCompletion()
        }

        providers += [FUIGoogleAuth(), FUIEmailAuth()]

        FUIAuth.defaultAuthUI()?.providers = providers
        FUIAuth.defaultAuthUI()?.shouldHideCancelButton = true
        FUIAuth.defaultAuthUI()?.customStringsBundle = Bundle.main
        FUIAuth.defaultAuthUI()?.delegate = authDelegate

Lastly, I set up an auth state change listener where I save the displayName on the user's profile and clear out the value from UserDefaults. There could be some more cleanup/error handling here (checking to see a the saved value exists when user.displayName is not nil, checking if commitChanges(_:) returns an error, etc) but this should be the general idea.

        Auth.auth().addStateDidChangeListener { (auth, user) in
            guard let user = user,
                  user.displayName == nil,
                  let displayName = UserDefaults.shared.string(forKey: "displayName") else { return }

            let changeRequest = user.createProfileChangeRequest()
            changeRequest.displayName = displayName
            changeRequest.commitChanges(completion: { (_) in
                UserDefaults.standard.setValue(nil, forKey: "displayName")
                UserDefaults.standard.synchronize()
            })
        }

@KrisConrad
Copy link
Author

KrisConrad commented Jan 14, 2021

Got another app rejection during an update review because this issue again today. Would be super cool if it was ever fixed.

@Arunperfutil
Copy link

is there any update on this?

@morganchen12
Copy link
Contributor

Hey @Arunperfutil, a fix is in review at https://github.com/firebase/FirebaseUI-iOS/pull/933/files and will be released soon.

@yuchenshi yuchenshi assigned morganchen12 and unassigned rosalyntan Jan 25, 2021
@morganchen12
Copy link
Contributor

This should be fixed in the latest version of FirebaseUI. Please let me know if that's not the case.

@romrell4
Copy link

romrell4 commented Sep 8, 2021

I think I'm still encountering this issue, on the newest version. I'm using the built in defaultAuthUI, with Google, Facebook, Apple, and Email providers. I'm using the following to propagate changes to the app:

        Auth.auth().addStateDidChangeListener { (_, user) in
            print(user)
            print(user?.email)
            print(user?.displayName)
            self.user = user
        }

When I login with apple, I'm getting this in my logs:

Optional(<FIRUser: 0x283395480>)
Optional("<readacted>@gmail.com")
Optional("")

So the email is being persisted, but it looks like the name isn't. Any ideas if this is the same problem?

Even weirder... AFTER logging in with Apple, if I try to go back to logging in with Google or Facebook or something else, I continue receiving an empty string for the display name...

Then, if I go into the Firebase Auth console and delete the user - I can restart and recreate the error

Here's a screen recording showing the issue:
https://user-images.githubusercontent.com/15692420/132564881-941ea69e-30c5-4776-a277-ce5744ea21a0.mp4

Highlights:

  1. Started by deleting all users from Firebase console
  2. When logging in with Apple for the first time, user.displayName is nil
  3. After logging out and back into Apple, user.displayName is "" (empty string)
  4. After logging out and back into Apple, user.displayName is, once again, "" (empty string)
  5. After logging out and logging in with Google, user.displayName is "Eric Romrell"
  6. After logging out and back in with Google, user.displayName is "Eric Romrell" again
  7. After logging out and back in with Apple, user.displayName is "Eric Romrell"
  8. After logging out and back in with Apple, user.displayName is back to "" (empty string)
  9. (not included in video) After logging out and back in with Google, user.displayName continues to be "" (empty string).

So, it almost seems like logging in with Apple never gives the name, and ends up corrupting the other auth methods, so that the name is no longer available for any of them (?) @morganchen12 any ideas?

Here's the firebaseui portion of my podfile.lock:

  - FirebaseUI (12.0.2):
    - FirebaseUI/Anonymous (= 12.0.2)
    - FirebaseUI/Auth (= 12.0.2)
    - FirebaseUI/Database (= 12.0.2)
    - FirebaseUI/Email (= 12.0.2)
    - FirebaseUI/Facebook (= 12.0.2)
    - FirebaseUI/Firestore (= 12.0.2)
    - FirebaseUI/Google (= 12.0.2)
    - FirebaseUI/OAuth (= 12.0.2)
    - FirebaseUI/Phone (= 12.0.2)
    - FirebaseUI/Storage (= 12.0.2)

@morganchen12 morganchen12 reopened this Sep 9, 2021
@salami
Copy link

salami commented Mar 14, 2022

My app is getting rejected by Apple Review because of this. I'm going to try @KrisConrad suggestion but would be great if you guys could get this working.

Update - I do believe the changes from https://github.com/firebase/FirebaseUI-iOS/pull/933/files do work in updating the displayName on the user. The problem is that upon first log-in, what I was finding was that my addStateDidChangeListener would be called before the change from changeRequest.commitChanges would be propagated. Or at least that's my best guess.

So what I ended up doing was swizzling as recommended by @KrisConrad, however I am not calling changeRequest.commitChanges and simply storing the displayName on a singleton to be accessed during the first log-in process.

@morganchen12
Copy link
Contributor

Fixed upstream in Firebase Auth. firebase/firebase-ios-sdk#10068

@romrell4
Copy link

romrell4 commented Mar 28, 2023

So by closing this are we indicating that there should be no required changes within the auth UI library? Not even a version update? Should users of the library just start seeing the display name always populated for Apple login users? Cc @morganchen12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests