最初のサインイン部分は公式通りです。
func socialSignInWithWebUI() { Amplify.Auth.signInWithWebUI(for: .facebook, presentationAnchor: self.view.window!) { result in switch result { case .success: print("Sign in succeeded") case .failure(let error): print("Sign in failed \(error)") } } }
ここまででクライアント側はSocialSignInが完了します。
認証完了後にuserIDとemailを取得したい、みたいなシーンはよくあるかと思いますが、割と一筋縄ではいかないポイントです。
Amplify.Auth.getCurrentUser()
Firebase Authenticationを使ったことある方はまずこれを思い浮かぶかと思います。
しかしgetCurrentUser()
にはuserId
プロパティはありますが、email
プロパティはありません。
さらにuserId
プロパティは必ずnilで返却されてきます。おそろしい。
UserAttributes
Amazon CognitoのユーザープールにアクセスできるのがUserAttributes
です。
func fetchAttributes() { Amplify.Auth.fetchUserAttributes() { result in switch result { case .success(let attributes): print("User attributes - \(attributes)") case .failure(let error): print("Fetching user attributes failed with error \(error)") } } }
こんな感じでattributesに格納されAuthUserAttribute
の配列が取得されます。
通常であれば、AuthUserAttributeKeyでアクセスしてそのvalueを取得しますがemailとname以外AuthUserAttributeKeyがunknownとして格納されているように見えます。
本来であれば上記のAuthUserAttributeKeyが設定されているはずです。そしてAuthUserAttributeKeyの中にuserIdに該当するkeyは見当たりません。
ここでAndroidをみてみます。
AndroidはAWSMobileClient.getInstance().userAttributes["KEY"]
でアクセスしますが、
みたいな形で正常にAuthUserAttributeKeyが設定された状態で格納されています。
さらにAuthUserAttributeKeyのsub
のvalueにuserIdらしきものが入っています。
iOS側でlet email = attributes.filter({ $0.key.rawValue == "sub" }).first?.value
で抜き取ろうとすると成功します。
同じ容量でemailも取得することが可能です。
ちなみにAndroid側でAmplify.Auth.currentUser.userId
で取得した場合とAWSMobileClient.getInstance().userAttributes["sub"]
で取得する場合は同じuserIdが取得できるはずです。