Doorman + React Navigation
Customize your doorman navigation flow to work however you'd like.
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.

- 1.Create two custom screens
- 2.Turn the two screens into a stack
- 3.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
.Let's create our stack consisting of two screens –
PhoneScreen
and ConfirmScreen
in a file called Stack.js
.React Navigation v5
React Navigation v4
// Stack.js
import React from 'react'
import { useNavigation } from '@react-navigation/native'
import { AuthFlow } from 'react-native-doorman'
const Phone = () => {
const { navigate } = useNavigation()
return (
<AuthFlow.PhoneScreen
onSmsSuccessfullySent={() => {
navigate('Confirm')
}}
renderHeader={null}
/>
)
}
const Confirm = () => (
<AuthFlow.ConfirmScreen
renderHeader={null}
/>
)
// Stack.js
import React from 'react'
import { useNavigation } from 'react-navigation-hooks'
import { AuthFlow } from 'react-native-doorman'
const Phone = () => {
const { navigate } = useNavigation()
return (
<AuthFlow.PhoneScreen
onSmsSuccessfullySent={() => {
navigate('Confirm')
}}
renderHeader={null}
/>
)
}
const Confirm = () => (
<AuthFlow.ConfirmScreen
renderHeader={null}
/>
)
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.Let's edit the
Stack.js
code to add a stack navigator
.We'll import
createStackNavigator
and export our new stack, like this:React Navigation v5
React Navigation v4
// Stack.js
import { createStackNavigator } from '@react-navigation/stack'
// ... other code from step #1
const Stack = createStackNavigator()
const AuthStack = () => (
<Stack.Navigator>
<Stack.Screen name="Phone" component={Phone} />
<Stack.Screen name="Confirm" component={Confirm} />
</Stack.Navigator>
)
export default AuthStack
// Stack.js
import { createStackNavigator } from 'react-navigation-stack'
// ...other code from Stack.js (in step #1)
const AuthStack = createStackNavigator({
Phone,
Screen
})
export default AuthStack
Here is the final
Stack.js
file:React Navigation v5
React Navigation v4
import React from 'react'
import { useNavigation } from '@react-navigation/native'
import { createStackNavigator } from '@react-navigation/stack'
import { AuthFlow } from 'react-native-doorman'
const Phone = () => {
const { navigate } = useNavigation()
return (
<AuthFlow.PhoneScreen
onSmsSuccessfullySent={() => {
navigate('Confirm')
}}
renderHeader={null}
/>
)
}
const Confirm = () => (
<AuthFlow.ConfirmScreen
renderHeader={null}
/>
)
const Stack = createStackNavigator()
const AuthStack = () => (
<Stack.Navigator>
<Stack.Screen name="Phone" component={Phone} />
<Stack.Screen name="Confirm" component={Confirm} />
</Stack.Navigator>
)
export default AuthStack
import React from 'react'
import { useNavigation } from 'react-navigation-hooks'
import { createStackNavigator } from 'react-navigation-stack'
import { AuthFlow } from 'react-native-doorman'
const Phone = () => {
const { navigate } = useNavigation()
return (
<AuthFlow.PhoneScreen
onSmsSuccessfullySent={() => {
navigate('Confirm')
}}
renderHeader={null}
/>
)
}
const Confirm = () => (
<AuthFlow.ConfirmScreen
renderHeader={null}
/>
)
const AuthStack = createStackNavigator({
Phone,
Screen
})
export default AuthStack
We now have a working React Navigation stack for our
AuthFlow
! How easy was that?The final step is making these actually work with Doorman's phone authentication. We'll see that in step 3.
Let's start by creating a simple
App.js
file that initializes Firebase and adds React Navigation's app container.React Navigation v5
React Navigation v4
// App.js
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
// initialize firebase
import firebase from 'firebase/app'
import 'firebase/auth'
firebase.initializeApp(YOUR_FIREBASE_CONFIG)
// create our App component, shown once we've authed
const AuthedApp = () => (
<Text
onPress={() => firebase.auth().signOut()}
style={{ paddingTop: 300, color: 'blue', fontSize: 24 }}
>
This app is authed!!
</Text>
)
const App = () => {
return (
<NavigationContainer>
</NavigationContainer>
);
}
export default App
// App.js
import * as React from 'react';
// initialize firebase
import firebase from 'firebase/app'
import 'firebase/auth'
firebase.initializeApp(YOUR_FIREBASE_CONFIG)
// create our App component, shown once we've authed
const AuthedApp = () => (
<Text
onPress={() => firebase.auth().signOut()}
style={{ paddingTop: 300, color: 'blue', fontSize: 24 }}
>
This app is authed!!
</Text>
)
const App = () => {
return (
<>
// we'll update this in the next step
</>
);
}
export default App
If you already have an app created (you probably do), then you can replace
AuthedApp
above with your App
component.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
.React Navigation v5
React Navigation v4
// App.js
import * as React from 'react'
import { DoormanProvider, AuthGate } from 'react-native-doorman'
import AuthStack from './Stack'
// initialize firebase
import firebase from 'firebase/app'
import 'firebase/auth'
firebase.initializeApp(YOUR_FIREBASE_CONFIG)
// create our App component, shown once we've authed
const AuthedApp = () => (
<Text
onPress={() => firebase.auth().signOut()}
style={{ paddingTop: 300, color: 'blue', fontSize: 24 }}
>
This app is authed!!
</Text>
)
const App = () => {
return (
<NavigationContainer>
<DoormanProvider publicProjectId="YOUR-PROJECT-ID">
<AuthGate>
{({ user, loading }) => {
if (loading) return <></>
// if a user is authenticated
if (user) return <AuthedApp />
// otherwise, send them to the auth flow
return <AuthStack />
}}
</AuthGate>
</DoormanProvider>
</NavigationContainer>
);
}
export default App
// App.js
import { DoormanProvider, AuthGate } from 'react-native-doorman'
import { createAppContainer } from 'react-navigation'
import AuthStack from './Stack' // <-- made in step #2 😇
const Navigator = createAppContainer(AuthStack)
// initialize firebase
import firebase from 'firebase/app'
import 'firebase/auth'
firebase.initializeApp(YOUR_FIREBASE_CONFIG)
// create our App component, shown once we've authed
const AuthedApp = () => (
<Text
onPress={() => firebase.auth().signOut()}
style={{ paddingTop: 300, color: 'blue', fontSize: 24 }}
>
This app is authed!!
</Text>
)
const App = () => {
return (
<DoormanProvider publicProjectId="YOUR-PROJECT-ID">
<AuthGate>
{({ user, loading }) => {
if (loading) return <></>
// if a user is authenticated
if (user) return <AuthedApp />
// otherwise, send them to the auth flow
return <Navigator />
}}
</AuthGate>
</DoormanProvider>
);
}
export default App
Let's recap what we did above.
- 1.Import the
DoormanProvider
andAuthGate
components fromreact-native-doorman
into yourApp.js
, and place them inside theNavigationContainer
. - 2.Place them within the
NavigationContainer
(if you're usingv5
.) - 3.
- 4.If there is a
user
, meaningDoorman
has authenticated someone using Firebase auth, we render ourAuthedApp
component. - 5.Otherwise, we render our custom
AuthStack
flow fromStack.js
.
Here's the final
App.js
:React Navigation v5
React Navigation v4
// App.js
import * as React from 'react';
import { DoormanProvider, AuthGate } from 'react-native-doorman'
import AuthStack from './Stack' // <-- made in step #2 😇
// initialize firebase
import 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 exists
const AuthedApp = () => (
<Text
onPress={() => firebase.auth().signOut()}
style={{ paddingTop: 300, color: 'blue', fontSize: 24 }}
>
This app is authed!!
</Text>
)
const App = () => {
return (
<NavigationContainer>
<DoormanProvider publicProjectId="YOUR-PROJECT-ID">
<AuthGate>
{({ user, loading }) => {
if (loading) return <></>
// if a user is authenticated
if (user) return <AuthedApp />
// otherwise, send them to the auth flow
return <AuthStack />
}}
</AuthGate>
</DoormanProvider>
</NavigationContainer>
);
}
export default App
// App.js
import * 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 firebase
import firebase from 'firebase/app'
import 'firebase/auth'
firebase.initializeApp(YOUR_FIREBASE_CONFIG)
// create react navigation container
const Navigator = createAppContainer(AuthStack)
// create our App component, shown once we've authed
// you can replace this with your App it exists
const AuthedApp = () => (
<Text
onPress={() => firebase.auth().signOut()}
style={{ paddingTop: 300, color: 'blue', fontSize: 24 }}
>
This app is authed!!
</Text>
)
const App = () => {
return (
<DoormanProvider publicProjectId="YOUR-PROJECT-ID">
<AuthGate>
{({ user, loading }) => {
if (loading) return <></>
// if a user is authenticated
if (user) return <AuthedApp />
// otherwise, send them to the auth flow
return <AuthStack />
}}
</AuthGate>
</DoormanProvider>
);
}
export default App
🔥Doorman added! Your React Native / Expo app now has Firebase phone auth, made custom with React Navigation.
Want to customize the styles of your screens? See docs for the
AuthFlow.PhoneScreen
and AuthFlow.ConfirmScreen
.Last modified 3yr ago