Today, I tried for the first time to use AWS Amplify on my new project trustio.co. I am impressed by how many things you can do compared to Firebase, but at the same time I am also a little bit frustrated as the documentation is not that great.
For example, one use case where I tried to handle SignIn errors which in my opinion is a pretty basic thing to do. Instead of finding answers in their documentation, I had to find them on StackOverflow.
For example, if I had to solve this problem with Google Firebase, I would just found it explained in their docs, shortly and clearly:
Eventually, I gave up and decided to use their UI Components as it could save me a lot of time! But, it turned out that it has its own pitfalls...
After linking their component with my app pretty fast, I spent a few more hours figuring out why withAuthenticator
wouldn't accept my theme
param.
Update: AWS Amplify team has reached me the same day this article was posted, fixed the bug and released a new version of aws-amplify-react-native: 4.3.2 that contains the bug fix (64357b1). Supper responsive! Kuddos to them! 🔥
In their documentation is shown clearly that I can pass the theme
param in the second param of the withAuthenticator
component which should be defined in an object:
It turns out it's not how it actually works in their codebase!
Disclaimer: Prepare for some dirty work... 🧐
Let's look at the actual component :
/* aws-amplify-react-native/src/Auth/index.tsx */
export function withAuthenticator<Props extends object>(
Comp: React.ComponentType<Props>,
includeGreetings = false,
authenticatorComponents = [],
federated = null,
theme: AmplifyThemeType = null,
signUpConfig: ISignUpConfig = {}
) {
/* ... */
if (typeof includeGreetings === 'object' && includeGreetings !== null) {
this.authConfig = Object.assign(this.authConfig, includeGreetings);
} else {
this.authConfig = {
includeGreetings,
authenticatorComponents,
signUpConfig,
};
/* ... */
Okay, so, we can clearly see that our withAuthenticator
component accepts multiple parameters, one of which is theme
param. Also, you can see the if statement which basically says that in case the second param - includeGreetings
in withAuthenticator
is specified as an object, we are gonna treat it as a param with multiple options inside. If not, then we are just gonna assume that the user wants to specify params by comma instead. So far, so good!
* However, I am not that happy with this implementation as it's quite inconsistent. It would be better if the second parameter was just an object to keep things consistent and not confuse people. Moreover, this is not documented anywhere, so I had to discover this by myself which is not a good sign...
Okay, let's move on...
If we scroll down, we can see that eventually, withAuthenticator
is just a wrapper around Authenticator
component. But...!
/* ... */
return (
<Authenticator
{...this.props}
hideDefault={ this.authConfig.authenticatorComponents && this.authConfig.authenticatorComponents.length > 0 }
signUpConfig={this.authConfig.signUpConfig}
onStateChange={this.handleAuthStateChange}
children={this.authConfig.authenticatorComponents}
usernameAttributes={this.authConfig.usernameAttributes}
theme={theme}
/>
);
/* ... */
you can see that the theme prop in Authenticator
is taken from our withAuthenticator
props directly! Not from this.authConfig
object! This creates problems as you might think that you can specify the theme
prop in an object and it will be used by the Authenticator
component as shown in the official AWS Documentation , but in reality, it's not how it works...
So, how do you fix this?
export default withAuthenticator(App, {
includeGreetings: true,
usernameAttributes: 'email',
signUpConfig: AmplifySignUpConfig,
},
undefined,
undefined,
AmplifyTheme
});
Not the best solution, but indeed it works as Authenticator
component would only take the theme
prop from the 4th param of withAuthenticator
and not from the 2nd param. 🤷♂️
At this point, you might ask, why don't you just use the Authenticator
component and be done already... Well, I don't want to show the SignOut button after the user logged in the app, but in order to do that, I would have to specify manually which components should Authenticator
have and which not. Which in turn, adds more code and feels less intuitive. Where in the withAuthenticator
example, I can just specify a prop like this: includeGreetings: false
and it makes it really easy to switch things around in development.
As one of the podcasters I follow said:
If you want something done, roll up your sleeves and get to work!
So I might just go on the official repo and open a pull request or just an issue if I am lazy 😁
This is just the first day me working with AWS Amplify, so maybe things will get easier from there or maybe not... 😳 But I do believe AWS Amplify is a better option than firebase, so, let's see...
If you believe I made a mistake and it's not AWS's fault, please correct me in the comments! Would really appreciate it!
That's it for today friends! I will keep you posted on things I learn along the way of building the trustio.co app. Until then, have an amazing rest of your day! See you tomorrow! 😊
p.s 🤫 I recently started a podcast called The Anxious Developer where I share my knowledge on how to reduce your stress, become more present and productive as a Developer. I would love to hear your thoughts on it! 😊
Remember, you are worthy, you are loved and you matter! Have a great day! ❤️