# Getting started with Firebase Authentication on React Native - https://medium.com/@chrisbianca/getting-started-with-firebase-authentication-on-react-native-a1ed3d2d6d91 There are no two ways about it, **Authentication is hard to do right**. Fortunately, with the introduction of a new breed of Authentication-as-a-Service providers like [Firebase](https://firebase.google.com/docs/auth/) and [Auth0](https://auth0.com/), you're never going to have to worry about Authentication ever again. They've gone and taken away all the stress of OAuth tokens, refresh tokens, passwords, encryption, et al, and hidden it behind a set of easy to understand APIs so all you need to think about is how best to integrate it into your app. In this walkthrough, I'm going to talk through some of the best practices and building blocks for how to integrate Firebase Authentication with React Native. ![](https://cdn-images-1.medium.com/max/800/1*NWZFqZxUpD31KioZ9w3poA.jpeg) ## Why Firebase Authentication? Even if you have no interest in using any of the many other Firebase features you should still consider using Firebase Authentication as your Auth solution, and here's why: - The breadth of available Auth providers: Email/Password, Phone number, Facebook, Google, Twitter, GitHub, Anonymous and even integration with custom authentication providers are all supported. - You can easily link accounts from multiple providers. - There are SDKs for Web, iOS, Android, C++, and Unity apps, an Admin SDK for backend servers running Node, Java and Python, plus our very own react-native-firebase for React Native. - It's backed by Firebase, so it will scale with your usage indefinitely. - It intergrates nicely with [Cloud Founctions for Firebase](https://firebase.google.com/docs/functions/) so if you want to send an email to your newly registred user, you can do so without the need for a server. - It's completely free (other than the SMSs used for Phone Authentication). Sold right? Well, let's get you started with Firebase Authentication and React Native. ## Project setup You can either make use of our [starter app](http://invertase.link/starter) or you can choose to add `react-native-firebase` manually to an existing project (the docs are [here](https://rnfirebase.io/docs/v3.1.*/installation/initial-setup)). ### A quick word on forms and React Native Before we start, it's worth nothing that interaction with Firebase Auth requires the user of forms to collect user data. To keep this tutorial clean and focused on Firebase rather than forms and UI, I'm not going to include the collection of data in my examples. I will leave it up to you to decide whether to just use the standard React Native **TextInput** component backed by the Component state or to go for a more fully managed library like **redux-form**. As such, the examples and code below will be focusing on what happens after the user has clicked the submit button and make the assumption that the form values are available in the Component's state object. Note: My personal preference is to go for the excellent **redux-form** library as it will save you no end of boilerplate, as well as offering built-in support for validation and error handling ## Checking the current authentication state But we haven't signed anybody in yet...? ## Registration and Login Users are automatically created the first time they sign in to your app using one of the supported Firebase authentication methods. This means that the registration and login flows are almost identical, with one small caveat: for email/password authentication there is an explocit `createUserWithEmailAndPassword` method which can be used to create the user. ### Email and Password authentication This really is the easiest authentication method to get up and running; simply set up a form to collect the user's email address and their password and pass it through to Firebase: ```javascript onLogin = () => { const { email, password } = this.state; firebase.auth().signInWithEmailAndPassword(email, password) .then((user) => { // If you need to do anything with the user, do it here // The user will be logged in automatically by the // `onAuthStateChanged` listener we set up in App.js earlier }) .catch((error) => { const { code, message } = error; // For details of error codes, see the docs // The message contains the default Firebase string // representation of the error }); } onRegister = () => { const { email, password } = this.state; firebase.auth().createUserWithEmailAndPassword(email, password) .then((user) => { // If you need to do anything with the user, do it here // The user will be logged in automatically by the // `onAuthStateChanged` listener we set up in App.js earlier }) .catch((error) => { const { code, message } = error; // For details of error codes, see the docs // The message contains the default Firebase string // representation of the error }); } ``` ### Phone authentication Using phone authentication is a little more involved as it is a multi-step process which can differ between iOS and Android. The basic flow for phone authentication is as follows: 1. The user enters their phone number 2. Firebase sends a verification code to the user's phone 3. The user enters the verification code 4. Firebase confirms that the verification code matches and signs the user in However, on Android, the Firebase library and Google Play Services are able to verify the user's phone automatically. When this happends, steps 3 and 4 are no longer required. I won't lie, ther were many discussions trying to come up with an implementation for `react-native-firebase` that was simple, but equally flexible. In the end, we ended up settling for tow different methods: - `signInWithPhoneNumber` - a more straightforward implementation that provides less complexity and logs the user in automatically at the end of the process. - `verifyPhoneNumber` - gives the developer complete control, by providing feedback on the current verification state and requres you to manually log the user in once confirmed As we're only interested in login and registration, this tutorial will focus on the `signInWithPhoneNumber` method. For those who are interested, we provider a complete `verifyPhoneNumber` example in the `react-native-firebase` [documentation](https://rnfirebase.io/docs/v3.1.*/auth/phone-auth#verifyPhoneNumber) You'll need to set up two separate forms: one to take the phone number, and one to take the verification code. You'll start by showing the phone number form, then hide it and display the verification code form once you've had confirmation that the verification SMS has beeen sent. ```javascript onLoginOrRegister = () => { const { phoneNumber } = this.state; firebase.auth().signInWithPhoneNumber(phoneNumber) .then((confirmResult) => { // This means that the SMS has been sent to the user // You need to: // 1) Save the `confirmResult` object to use later this.setState({ confirmResult }); // 2) Hide the phone number form // 3) Show the verification code form }) .catch((error) => { const { code, message } = error; // For details of error codes, see the docs // The message contains the default Firebase string // representation of the error }); } onVerificationCode = () => { const { confirmResult, verificationCode } = this.state; confirmResult.confirm(verificationCode) .then((user) => { // If you need to do anything with the user, do it here // The user will be logged in automatically by the // `onAuthStateChanged` listener we set up in App.js earlier }) .catch((error) => { const { code, message } = error; // For details of error codes, see the docs // The message contains the default Firebase string // representation of the error }); } ``` ## Social Authentication Firebae supports a number of different social authentication providers: Facebook Google, Twitter and GitHub. It does this by providing a way to build a credential that is specific to each of the providers, coupled with the `signInWithCredential` method. What Firebase and `react-native-firebase` doesn't offer is a built-in way of obtaining this credential from the Social Provider itself. Instead, you'll need to use additional libraries to handle thi sign in flow and retrieval of the access token required. I'll give an example for both Facebook and Google below. ### Facebook For Facebook authentication we recommend the official `react-native-fbsdk` library available [here](https://github.com/facebook/react-native-fbsdk). You'll need to follow their setup instructions for iOS and Android as well as create app in the Facebook Developers console as explained in their setup guide. this can be a bit fiddly, but the setup instructions are generally easy to follow. Once `react-native-fbsdk` is setup, using Facebook with Firebase Authentication is very straightforward: simple add a button to your UI which calls the following handler: ```javascript import { AccessToken, LoginManager } from 'react-native-fbsdk'; onLoginOrRegister = () => { LoginManager.logInWithReadPermissions(['public_profile', 'email']) .then((result) => { if (result.isCancelled) { return Promise.reject(new Error('The user cancelled the request')); } // Retrieve the access token return AccessToken.getCurrentAccessToken(); }) .then((data) => { // Create a new Firebase credential with the token const credential = firebase.auth.FacebookAuthProvider.credential(data.accessToken); // Login with the credential return firebase.auth().signInWithCredential(credential); }) .then((user) => { // If you need to do anything with the user, do it here // The user will be logged in automatically by the // `onAuthStateChanged` listener we set up in App.js earlier }) .catch((error) => { const { code, message } = error; // For details of error codes, see the docs // The message contains the default Firebase string // representation of the error }); } ``` ### Google For Google Authentication we recommend the `react-native-google-signin` library available [here](https://github.com/devfd/react-native-google-signin). As with Facebook, you'll have to follow their setup guides and register an application with Google. Once `react-native-google-signin` is setup, simply add a button to your UI which calls the following handler: ```javascript import { GoogleSignin } from 'react-native-google-signin'; onLoginOrRegister = () => { GoogleSignin.signIn() .then((data) => { // Create a new Firebase credential with the token const credential = firebase.auth.GoogleAuthProvider.credential(data.idToken, data.accessToken); // Login with the credential return firebase.auth().signInWithCredential(credential); }) .then((user) => { // If you need to do anything with the user, do it here // The user will be logged in automatically by the // `onAuthStateChanged` listener we set up in App.js earlier }) .catch((error) => { const { code, message } = error; // For details of error codes, see the docs // The message contains the default Firebase string // representation of the error }); } ``` ### Other Socail Providers Firebase also supports Twitter and GitHub authentication. We don't have a recommended third-party library for either of these solutions at present, but please let me know if there's one you feel we should be endorsing As with Facebook and Google auth, you'll need to use our provider class to create the credential that Firebase requires. Just check out the docs on [TwitterAuthProvider](https://rnfirebase.io/docs/v3.1.*/auth/reference/TwitterAuthProvider) and [GithubAuthProvider](https://rnfirebase.io/docs/v3.1.*/auth/reference/GithubAuthProvider) for more information. ## Accessing the current user Once registered and logged in, you'll want to be able to access the logged in user to get at information like their name and profile picture. This is nice and easy by just calling `firebase.auth().currentUser` - details of what's available on the User object can be found [here](https://rnfirebase.io/docs/v3.0.*/auth/reference/User). ## What else does Firebae Authentication offer? With login and registration covered, here's a quick overview of some of the other things Firebase Authentication can do: - **firebase.auth().currentUser.linkWithCredential()** - allows the user account to be linked with multiple authentication providers. - **firebase.auth().currentUser.reauthenticateWithCredential()** - for some operations, Firebase will require the user to have logged in recently. This method allows the user to be re-authenticated using any of the authentication providers they've been linked with - **firebase.auth().sendPasswordResetEmail()** - triggers an email to the user's email, allowing them to reset their password. The emails are completely customisable from the Firebase console, whilst the webpages needed as part of the process are hosted by Firebase themselves. This is by no means a compete list - to check out what else Firebase and `react-natvie-firebase` support see our [reference docs](https://rnfirebase.io/docs/v3.0.*/auth/reference/auth).