Describe the bug
I am working on a React Native project.
When I sign up using Google I can successfully create an account but the property email_verified
is not set which means that the app interprets the user as not verified.
Screenshots
Environment
System:
OS: macOS 10.15.3
CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
Memory: 229.88 MB / 16.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 12.11.0 - /usr/local/bin/node
Yarn: 1.19.2 - ~/.yarn/bin/yarn
npm: 6.11.3 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
Browsers:
Chrome: 80.0.3987.132
Firefox: 72.0.2
Safari: 13.0.5
npmPackages:
@babel/core: ^7.6.2 => 7.8.3
@babel/runtime: ^7.6.2 => 7.8.3
@carimus/metro-symlinked-deps: ^1.1.0 => 1.1.0
@formatjs/intl-pluralrules: ^1.5.0 => 1.5.0
@formatjs/intl-relativetimeformat: ^4.5.7 => 4.5.7
@invertase/react-native-apple-authentication: ^0.1.1 => 0.1.1
@react-native-community/datetimepicker: ^2.2.2 => 2.2.2
@react-native-community/eslint-config: ^0.0.5 => 0.0.5
@react-native-community/masked-view: ^0.1.6 => 0.1.6
@react-native-community/netinfo: ^5.5.1 => 5.5.1
amazon-cognito-identity-js: ^3.2.5 => 3.2.5
aws-amplify: ^2.2.6 => 2.2.6
aws-amplify-react-native: ^3.2.2 => 3.2.2
babel-jest: ^24.9.0 => 24.9.0
date-fns: ^2.10.0 => 2.10.0
eslint: ^6.5.1 => 6.8.0
jest: ^24.9.0 => 24.9.0
metro-react-native-babel-preset: ^0.56.0 => 0.56.4
query-string: ^6.11.1 => 6.11.1
react: 16.9.0 => 16.9.0
react-intl: ^3.11.0 => 3.11.0
react-native: 0.61.5 => 0.61.5
react-native-device-info: ^5.4.1 => 5.4.1
react-native-gesture-handler: ^1.5.3 => 1.5.3
react-native-inappbrowser-reborn: ^3.3.4 => 3.3.4
react-native-linear-gradient: ^2.5.6 => 2.5.6
react-native-localize: ^1.3.2 => 1.3.2
react-native-modal: ^11.5.4 => 11.5.4
react-native-reanimated: ^1.7.0 => 1.7.0
react-native-safe-area-context: ^0.6.2 => 0.6.2
react-native-screens: ^2.0.0-alpha.25 => 2.0.0-alpha.25
react-native-spinkit: ^1.5.0 => 1.5.0
react-native-vector-icons: ^6.6.0 => 6.6.0
react-navigation: ^4.0.10 => 4.0.10
react-navigation-stack: ^2.0.15 => 2.0.15
react-navigation-tabs: ^2.7.0 => 2.7.0
react-test-renderer: 16.9.0 => 16.9.0
npmGlobalPackages:
@aws-amplify/cli: 4.16.0
@twilio/autopilot-cli: 0.0.27
undefined: 1.2.7
aws-amplify-monorepo: 0.1.30
gatsby-cli: 2.7.45
lighthouse: 4.2.0
nodemon: 1.18.7
npm: 6.11.3
sequelize-cli: 5.4.0
Smartphone (please complete the following information):
Additional context
It's a React Native app.
@elledienne This seems to be related specifically to Amazon Cognito. We are currently discussing this issue internally and will provide an update once I have one.
@sammartinez Thanks a lot for your prompt answer, happy to support with testing/ experiment if that's helpful :)
@elledienne This seems to be related specifically to Amazon Cognito. We are currently discussing this issue internally and will provide an update once I have one.
Hi Sam, do you have an update on this?
@elledienne Circling back, still waiting to hear from Amazon Cognito on this, apologizes on the delay.
@elledienne Thanks for being patient so there was a couple follow up questions to this, are you providing an attribute mapping for Google for the email_verified attribute? Amazon Cognito did state by default they assume that any email/phone number they get from the result of a federated sign up or sign in is not verified so they don not set any values for the attribute for the user.
Another note, the returned attribute from the IdP also has to have the value be set to the string "true" in order for us to set email_verified to true
@elledienne Thanks for being patient so there was a couple follow up questions to this, are you providing an attribute mapping for Google for the email_verified attribute? Amazon Cognito did state by default they assume that any email/phone number they get from the result of a federated sign up or sign in is not verified so they don not set any values for the attribute for the user.
Another note, the returned attribute from the IdP also has to have the value be set to the string "true" in order for us to set email_verified to true
That's embarrassing - I fixed the attributes mapping and now it works like a charm! @sammartinez thanks for the help and sorry for posting a non-issue :)
For those who discover this issue via Google, here are the related Cognito docs:
Specifying Identity Provider Attribute Mappings for Your User Pool (AWS Management Console)
Example app:
I was running into the same problem because I didn't notice that there is a "email_verified" attribute on Googles side to map to. This fixed my problems with the Google IDP, thank you!
But how do you set the email_verified attribute for Facebook, Apple or any other IDP that does not offer the email_verified attribute? I am currently implementing social logins into my React Native app using the Amplify HOC. Without the email_verified attribute, the user is always redirected to the verifyContact-Component where the confirmation code, which usually gets send via email, should be entered. Using social logins, this is not the desired behaviour.
I have not been able to find documentation on this when using federated logins and the amplify HOC. Any help would be very appreciated.
This issue has been automatically closed because of inactivity. Please open a new issue if are still encountering problems.
@tim
I was running into the same problem because I didn't notice that there is a "email_verified" attribute on Googles side to map to. This fixed my problems with the Google IDP, thank you!
But how do you set the email_verified attribute for Facebook, Apple or any other IDP that does not offer the email_verified attribute? I am currently implementing social logins into my React Native app using the Amplify HOC. Without the email_verified attribute, the user is always redirected to the verifyContact-Component where the confirmation code, which usually gets send via email, should be entered. Using social logins, this is not the desired behaviour.
I have not been able to find documentation on this when using federated logins and the amplify HOC. Any help would be very appreciated.
Did you managed to verify the email address from facebook?
I have the same issue, using react native, google works fine but facebook requires an extra step to have the email verified
@ionutmiftode I actually did! Its not the way I would have chosen in the first place, but for my app it actually works perfect:
The key is too use a "post confirmation trigger" and set the attribute through the AWS SDK itself (adminUpdateUserAttributes Method).
The following code works for me:
var aws = require('aws-sdk');
aws.config.update({region: 'eu-central-1'});
exports.handler = (event, context, callback) => {
if (event.request.userAttributes.email) {
if (event.request.userAttributes["cognito:user_status"] === "EXTERNAL_PROVIDER") {
const cognitoIdServiceProvider = new aws.CognitoIdentityServiceProvider({
apiVersion: '2016-04-18',
region: 'eu-central-1'
});
var params = {
UserAttributes: [
{
Name: "email_verified",
Value: "true"
}
],
UserPoolId: event.userPoolId,
Username: event.userName
}
cognitoIdServiceProvider.adminUpdateUserAttributes(params, function(err, data) {
if (err) {
callback(null, event);
} else {
callback(null, event);
}
});
} else {
callback(null, event);
}
} else {
callback(null, event);
}
};
What it does is: After the user authenticates successfully via federation, the post confirmation trigger is always invoked. At this point in time, the user fully exists within the user pool and can be updated through the AWS SDK for cognito.
That means, that from within the Lambda function above, I use the cognito SDK itself to update the user and set the “email_verified”-Attribute through the adminUpdateUserAttributes()-Method.
I do this only for federated users (user_status === EXTERNAL_PROVIDER), since I don’t want to mess with the already working post confirmation workflow for users that are registering via email.
The trigger also seems to be updating the attribute through the SDK fast enough so that my App (React Native in my case) does not even try to send the user to the “verify email”-Screen. This is exactly the behavior I was hoping for.
Keep in mind that your lambda execution role needs the "_cognito-idp:AdminUpdateUserAttributes_" permission to update the attributes through the SDK.
We rolled out this solution to production on May 10th and haven't had any issues with it since and noticed around 30 user registrations via Facebook and Apple without any complaints.
While this is working I still don't understand why we have to go this route. Having to verify the users email address if the users comes from a federated service does not make sense to me at all.
I hope this solution works for you as well! Feel free to contact me if you need any help :)
that's awesome @timoschlueter
I'll give it a try! Also do you use profile picture from facebook? I saw that the picture format is not coming as expected form, it gets stored as an object that has a prop with the profile picture, while from google comes as an url - the expected format
@ionutmiftode unfortunately not. Our app uses just the email address :(
@timoschlueter used your solution, works as expected! I also fixed the profile picture issue here which is great!
One more thing, I added the logic in 'Post Authentication' lambda trigger, but this one is called when user sign in, not when he sign up, so I think the logic should be added in a Post Sign-up lambda trigger, but there is no such option.
the options from amplify cli for lambda trigger are:
Any idea which one I should use? Thanks
EDIT: So the winner is Post Confirmation :D
FYI: @timoschlueter and @ionutmiftode
Real pain in the rear <3, Bradley
@slatted because of your finding I just checked our Cognito user pool and indeed found a few external users (< 10%) with email_verified still set to false. I haven't noticed this before. Thanks for the info! I switched to a Post Authentication trigger as you suggested. Still seems to work as expected.
Really looks like a race condition.
I can't stress this enough: The fact that we have to use such a hack in the first place is really frustrating. :(
TY @slatted We ended up using both Post Authentication and Post Confirmation to solve the problem :smile:
@ionutmiftode , :) awesome
@timoschlueter , totally agree, a bunch of Cognito aspects seem unfinished (or atleast unpolished). I have a support case open with Amazon, if I get any headway there, I'll update the thread.
FYI @timoschlueter , @ionutmiftode :
Thank you for sharing the detailed use-case.
Using our internal tools, I found that there is an ongoing feature request for the ability to set "email_verified" to true via Cognito console. I have gone ahead and added your voice to the feature request. However please understand, being from Premium Support, I do not have visibility regarding service team's product roadmap and backlog and therefore, will not be able to provide an ETA as to when the feature will be released. As soon as it gets released, it should be publicly announced in either [1][2].
Amazon Cognito invokes Post Authentication trigger after signing in a user, allowing you to add custom logic after authentication. Until the feature is released, you can update "email_verified" attribute using "AdminUpdateUserAttributes" API in a Post Authentication trigger which you have already implemented. Please note once the user has sign-up, this trigger will be executed for every future successful sign-in.
So looks like our path forward is the right one (for now), and hopefully they move forward on the roadmap item at somepoint.
<3
Most helpful comment
I was running into the same problem because I didn't notice that there is a "email_verified" attribute on Googles side to map to. This fixed my problems with the Google IDP, thank you!
But how do you set the email_verified attribute for Facebook, Apple or any other IDP that does not offer the email_verified attribute? I am currently implementing social logins into my React Native app using the Amplify HOC. Without the email_verified attribute, the user is always redirected to the verifyContact-Component where the confirmation code, which usually gets send via email, should be entered. Using social logins, this is not the desired behaviour.
I have not been able to find documentation on this when using federated logins and the amplify HOC. Any help would be very appreciated.