Firebaseui-ios: When using Sign In with Apple to create an account displayName value of the auth user is not being set

Created on 16 Dec 2019  路  23Comments  路  Source: firebase/FirebaseUI-iOS

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

Most helpful comment

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.

All 23 comments

Closing this in favor of https://github.com/firebase/firebase-ios-sdk/issues/4393. We'll continue updating the issue there.

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

@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 https://github.com/firebase/firebase-ios-sdk/issues/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
  // ...
}

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

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.

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.

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

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

No, no ETA. :(

@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/

I'll aim to solve it before then.

@morganchen12 , any update on this?

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

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.

@morganchen12 Deadline has been moved to June 30.

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

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

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

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

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.

@rosalyntan Would you mind looking into this?

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()
            })
        }

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

is there any update on this?

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

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

Was this page helpful?
0 / 5 - 0 ratings