React Navigation is an incredible library for managing navigation in React Native apps. This example shows how to integrate it with Doorman, for both v4 and v5.
Doorman lets you add Firebase phone authentication to React Native and Expo apps with just a few lines of code. It provides a customizable UI, all the phone verification without a server, and you don't have to detach from Expo.
If you want to jump ahead, you can see the final code on Github (v5 code / v4 code).
What we're making
Let's recreate the quintessential Doorman auth flow, as seen in our welcome page.
Steps
Create two custom screens
Turn the two screens into a stack
Add authentication functionality to our custom stack
Our example will have two files only: App.js and Stack.js. We'll start with Stack.js.
This guide assumes you've already gone through the installation steps for React Navigation.
1. Create two screens
Let's create our stack consisting of two screens – PhoneScreen and ConfirmScreen in a file called Stack.js.
All we did above was import the two pre-made screens from Doorman AuthFlow.ConfirmScreen & AuthFlow.PhoneScreen, and put them into their own components.
When an SMS is successfully sent, the onSmsSuccessfullySent function gets called. Here, we navigate to the confirm screen. In the next step, we'll add the actual navigation that lets us do that.
2. Turn our screens into a stack
Let's edit the Stack.js code to add a stack navigator.
We'll import createStackNavigator and export our new stack, like this:
If you already have an app created (you probably do), then you can replace AuthedApp above with your App component.
3.1 Add Doorman to your app
The rest is the same as the original quick example, with one difference: you replace Doorman's AuthFlow component with your custom AuthStack from Stack.js.
// App.jsimport*as React from'react'import { DoormanProvider, AuthGate } from'react-native-doorman'import AuthStack from'./Stack'// initialize firebaseimport firebase from'firebase/app'import'firebase/auth'firebase.initializeApp(YOUR_FIREBASE_CONFIG)// create our App component, shown once we've authedconstAuthedApp= () => ( <TextonPress={() =>firebase.auth().signOut()} style={{ paddingTop:300, color:'blue', fontSize:24 }} > This app is authed!! </Text>)constApp= () => {return ( <NavigationContainer> <DoormanProviderpublicProjectId="YOUR-PROJECT-ID"> <AuthGate> {({ user, loading }) => {if (loading) return <></>// if a user is authenticatedif (user) return <AuthedApp />// otherwise, send them to the auth flowreturn <AuthStack /> }} </AuthGate> </DoormanProvider> </NavigationContainer> );}exportdefault App
// App.jsimport { DoormanProvider, AuthGate } from'react-native-doorman'import { createAppContainer } from'react-navigation'import AuthStack from'./Stack'// <-- made in step #2 😇constNavigator=createAppContainer(AuthStack)// initialize firebaseimport firebase from'firebase/app'import'firebase/auth'firebase.initializeApp(YOUR_FIREBASE_CONFIG)// create our App component, shown once we've authedconstAuthedApp= () => ( <TextonPress={() =>firebase.auth().signOut()} style={{ paddingTop:300, color:'blue', fontSize:24 }} > This app is authed!! </Text>)constApp= () => {return ( <DoormanProviderpublicProjectId="YOUR-PROJECT-ID"> <AuthGate> {({ user, loading }) => {if (loading) return <></>// if a user is authenticatedif (user) return <AuthedApp />// otherwise, send them to the auth flowreturn <Navigator /> }} </AuthGate> </DoormanProvider> );}exportdefault App
Let's recap what we did above.
Import the DoormanProvider and AuthGate components from react-native-doorman into your App.js, and place them inside the NavigationContainer.
Place them within the NavigationContainer (if you're using v5.)
Replace the DoormanProvider's publicProjectId prop with your own project ID.
If there is a user, meaning Doorman has authenticated someone using Firebase auth, we render our AuthedApp component.
Otherwise, we render our custom AuthStack flow from Stack.js.
Here's the final App.js:
// App.jsimport*as React from'react';import { DoormanProvider, AuthGate } from'react-native-doorman'import AuthStack from'./Stack'// <-- made in step #2 😇// initialize firebaseimport firebase from'firebase/app'import'firebase/auth'firebase.initializeApp(YOUR_FIREBASE_CONFIG)// create our App component, shown once we've authed// you can replace this with your App it existsconstAuthedApp= () => ( <TextonPress={() =>firebase.auth().signOut()} style={{ paddingTop:300, color:'blue', fontSize:24 }} > This app is authed!! </Text>)constApp= () => {return ( <NavigationContainer> <DoormanProviderpublicProjectId="YOUR-PROJECT-ID"> <AuthGate> {({ user, loading }) => {if (loading) return <></>// if a user is authenticatedif (user) return <AuthedApp />// otherwise, send them to the auth flowreturn <AuthStack /> }} </AuthGate> </DoormanProvider> </NavigationContainer> );}exportdefault App
// App.jsimport*as React from'react';import AuthStack from'./Stack'// <-- made in step #2 😇import { DoormanProvider, AuthGate } from'react-native-doorman'import { createAppContainer } from'react-navigation'// initialize firebaseimport firebase from'firebase/app'import'firebase/auth'firebase.initializeApp(YOUR_FIREBASE_CONFIG)// create react navigation containerconstNavigator=createAppContainer(AuthStack)// create our App component, shown once we've authed// you can replace this with your App it existsconstAuthedApp= () => ( <TextonPress={() =>firebase.auth().signOut()} style={{ paddingTop:300, color:'blue', fontSize:24 }} > This app is authed!! </Text>)constApp= () => {return ( <DoormanProviderpublicProjectId="YOUR-PROJECT-ID"> <AuthGate> {({ user, loading }) => {if (loading) return <></>// if a user is authenticatedif (user) return <AuthedApp />// otherwise, send them to the auth flowreturn <AuthStack /> }} </AuthGate> </DoormanProvider> );}exportdefault App
🔥Doorman added! Your React Native / Expo app now has Firebase phone auth, made custom with React Navigation.