User to DB code example
Let's see the code for adding a user to your database after they sign in.
Now that you've read the high-level explanation of adding a user to the database, let's see some code.
If you want to skip up to the code, you can see the example on Github. You can also scroll down to "Add user exists in DB logic."
Make sure you've already completed the setup guide, installation & have deployed your app before continuing.

TLDR

    1.
    Add a userExistsInDb state variable.
    2.
    Add onAuthStateChanged prop to DoormanProvider. This function gets called whenever the user signs in or out.
      1.
      Inside this function, call your DB to see if user exists already, and if not, send to the onboarding flow.
      2.
      Call setUserExistsInDb to update the state based on the DB's response.
    3.
    When userExistsInDb is false, render an Onboarding screen that lets users enter information, and then adds them to the database. This goes inside of AuthGate.
      1.
      Call setUserExistsInDb(true) when a user is successfully added to the DB from the Onboarding screen to update the state.

File overview

We're going to create 3 files. AuthLogic and Onboarding contain code distinct to this tutorial.
    App.tsx initialize Firebase, render app
    AuthLogic.tsx initialize Doorman, and conditionally render an authentication flow, an onboarding screen, or an authenticated app.
    Onboarding.tsx Collect user information if they aren't in the DB yet.

1. Initialize Firebase in App

App.tsx
1
import AuthLogic from './AuthLogic'
2
3
import firebase from 'firebase/app'
4
import 'firebase/auth'
5
import 'firebase/firestore' // <- if you use Firestore
6
7
if (!firebase.apps.length) {
8
// you can replace this with your firebase config
9
firebase.initializeApp({
10
apiKey: 'AIzaSyCn8HyP1tVZiagk-YvZRwjSwKdwQw5Pvng',
11
authDomain: 'tester-9d8bb.firebaseapp.com',
12
databaseURL: 'https://tester-9d8bb.firebaseio.com',
13
projectId: 'tester-9d8bb',
14
storageBucket: 'tester-9d8bb.appspot.com',
15
messagingSenderId: '760778283392',
16
appId: '1:760778283392:web:05cb35d0837c93c6584965',
17
})
18
}
19
20
export default AuthLogic
Copied!
This is simple boilerplate code that is no different than normal initialization for Firebase/Doorman.
You can replace the firebase.initializeApp config variable with your own firebase config.

2. Initialize Doorman in AuthLogic

This tutorial will rely on the DoormanProvider implementation instead of withPhoneAuth. (They both achieve the same thing, as mentioned in the quick example.)
First, create a component called AuthLogic.
AuthLogic.tsx
1
import React from 'react'
2
3
const AuthLogic = () => {
4
return <></>
5
}
6
7
export default AuthLogic
Copied!
Next, we'll add the Doorman Provider. This provider must wrap your entire app at the root file.
1
import React from 'react'
2
import { DoormanProvider } from 'react-native-doorman'
3
4
const AuthLogic = () => {
5
return (
6
<DoormanProvider publicProjectId="djzlPQFxxzJikNQgLwxN">
7
{/* Our auth logic will go here next. */}
8
</DoormanProvider>
9
)
10
}
11
12
export default AuthLogic
Copied!
You can replace the publicProjectId field with your own. How do I find my public Project Id?

2.1 Add AuthGate component

The AuthGate updates the state based on whether or not the user is authenticated.
1
import React from 'react'
2
import { DoormanProvider, AuthGate } from 'react-native-doorman'
3
4
const AuthLogic = () => {
5
return (
6
<DoormanProvider publicProjectId="djzlPQFxxzJikNQgLwxN">
7
<AuthGate></AuthGate>
8
</DoormanProvider>
9
)
10
}
11
12
export default AuthLogic
Copied!
AuthGate accepts a single child: a function that returns a component. It receives the user and loading fields as arguments.
1
<AuthGate>
2
{({ user, loading }) => {
3
// if loading auth listener
4
if (loading) return <></>
5
6
// if user is not authenticated
7
if (!user) return <AuthFlow />
8
9
// your actual app component, which appears after
10
// the user has authenticated
11
return <AfterAuth />
12
}}
13
</AuthGate>
Copied!
Whoa, where did AuthFlow come from? That's the Doorman component that lets your users sign in with phone number. AfterAuth is your normal app component.
Our file now looks like this:
AuthLogic.tsx (or .js if you don't use TypeScript)
1
import React from 'react'
2
import { DoormanProvider, AuthGate, AuthFlow } from 'react-native-doorman'
3
4
const AuthLogic = () => {
5
return (
6
<DoormanProvider publicProjectId="djzlPQFxxzJikNQgLwxN">
7
<AuthGate>
8
{({ user, loading }) => {
9
// if loading auth listener
10
if (loading) return <></>
11
12
// if user is not authenticated
13
if (!user) return <AuthFlow />
14
15
// your actual app component, which appears after
16
// the user has authenticated
17
return <AfterAuth />
18
}}
19
</AuthGate>
20
</DoormanProvider>
21
)
22
}
23
24
export default AuthLogic
Copied!

2.2 Add user exists in DB logic

Now, on to the code that lets you add your user to the DB.
First, let's add a userExistsInDb state variable, whose initial value is false. Add a checkingIfUserExists state variable too, which indicates if the DB check is loading or not.
1
const AuthLogic = () => {
2
const [userExistsInDb, setUserExistsInDb] = useState(false)
3
const [checkingIfUserExists, setCheckingIfUserExists] = useState(false)
4
5
// render code here
6
}
Copied!
Next, add a listener callback to the DoormanProvider component using its onAuthStateChanged prop.
1
const AuthLogic = () => {
2
const [userExistsInDb, setUserExistsInDb] = useState(false)
3
const [checkingIfUserExists, setCheckingIfUserExists] = useState(false)
4
5
const onAuthStateChanged = async (user) => {
6
if (user) {
7
const { uid } = user
8
9
setCheckingIfUserExists(true)
10
11
// user your own function here that calls your database to check
12
const exists = await checkIfUserExistsInDb(uid)
13
14
// if you're using Firestore, it might look like this:
15
const { exists } = await db.doc(`users/${uid}`).get()
16
17
// update the state based on our DB value
18
setUserExistsInDb(exists)
19
setCheckingIfUserExists(false)
20
} else {
21
// user is not signed in, reset the state to false
22
setUserExists(false)
23
setCheckingIfUserExists(false)
24
}
25
}
26
27
return (
28
<DoormanProvider
29
publicProjectId="djzlPQFxxzJikNQgLwxN"
30
onAuthStateChanged={onAuthStateChanged}
31
>
32
...
33
</DoormanProvider>
34
)
35
}
Copied!
The onAuthStateChanged prop is a function that gets called whenever the user signs in or out. It follows the same API from firebase.

2.3 Render Onboarding

The final step is to render an Onboarding screen if userExistsInDb is false.
1
// 👇 We'll create this in the final step
2
// you can import your own, too!
3
import Onboarding from './Onboarding'
4
5
...
6
7
<AuthGate>
8
{({ user, loading }) => {
9
// add checkingIfUserExists to loading condition
10
if (loading || checkingIfUserExists) return <></>
11
12
if (!user) return <AuthFlow />
13
14
// If user is authenticated, but doesn't exist in the DB,
15
// render the onboarding flow.
16
// We pass it a callback function called onUserAddedToDb
17
// this function will set userExistsInDb to true
18
// it gets called after the DB has been updated by <Onboarding />
19
if (!userExistsInDb) {
20
return (
21
<Onboarding
22
onUserAddedToDb={() => setUserExistsInDb(true)}
23
/>
24
)
25
}
26
27
// your actual app component, which appears after
28
// the user has authenticated
29
return <AfterAuth />
30
}}
31
</AuthGate>
Copied!
🎉That's it! All that's left is to make the Onboarding screen.
Here is our final AuthLogic screen, in its entirety:
1
import React, { useState } from 'react'
2
import { DoormanProvider, AuthGate, AuthFlow } from 'react-native-doorman'
3
import Onboarding from './Onboarding'
4
import AfterAuth from './AfterAuth'
5
import { db } from './db'
6
7
const AuthLogic = () => {
8
const [userExistsInDb, setUserExistsInDb] = useState(false)
9
const [checkingIfUserExists, setCheckingIfUserExists] = useState(false)
10
11
return (
12
<DoormanProvider
13
onAuthStateChanged={async user => {
14
if (user) {
15
const { uid } = user
16
17
setCheckingIfUserExists(true)
18
19
// 👇 user your own function here that calls your database to check
20
// const exists = await checkIfUserExistsInDb(uid)
21
22
// if you're using Firestore, it might look like this:
23
const { exists } = await db.doc(`users/${uid}`).get()
24
25
// update the state based on our DB value
26
setUserExistsInDb(exists)
27
setCheckingIfUserExists(false)
28
} else {
29
// user is not signed in, reset the state to false
30
setUserExistsInDb(false)
31
setCheckingIfUserExists(false)
32
}
33
}}
34
publicProjectId="djzlPQFxxzJikNQgLwxN"
35
>
36
<AuthGate>
37
{({ user, loading }) => {
38
// add checkingIfUserExists to loading condition
39
if (loading || checkingIfUserExists) return <></>
40
41
if (!user) return <AuthFlow />
42
43
// If user is authenticated, but doesn't exist in the DB,
44
// render the onboarding flow.
45
// We pass it a callback function called onUserAddedToDb
46
// this function will set userExistsInDb to true
47
// it gets called after the DB has been updated by <Onboarding />
48
if (!userExistsInDb) {
49
return (
50
<Onboarding onUserAddedToDb={() => setUserExistsInDb(true)} />
51
)
52
}
53
54
// your actual app component, which appears after
55
// the user has authenticated
56
return <AfterAuth />
57
}}
58
</AuthGate>
59
</DoormanProvider>
60
)
61
}
62
63
export default AuthLogic
64
65
Copied!
Note: If you have your own Onboarding screen (or React Navigation stack, you can render it in place of Onboarding.
    If you're using a React Navigation Stack in place of Onboarding (assuming it's with v5), then pass the onUserAddedToDb function as a param to your stack, and call it from your screen using useRoute().params.onUserAddedToDb.

3. Create <Onboarding /> screen

👋Don't forget to call the onUserAddedToDb function after successfully adding your user to the database, as seen in line 19 below! If you don't call it, the app won't re-render.
Here's an example of a basic Onboarding screen:
Onboarding.tsx
1
import React, { useState } from 'react'
2
import { TextInput, Button, View } from 'react-native'
3
import { useDoormanUser } from 'react-native-doorman'
4
5
const Onboarding = ({ onUserAddedToDb }) => {
6
const [name, setName] = useState('')
7
const { uid } = useDoormanUser()
8
9
const handleSubmit = async () => {
10
// Implement your own DB function here
11
await addUserToDb({ uid, name })
12
13
// ...if you're using Firestore, it might look like:
14
await db.doc(`users/${uid}`).set({ name }, { merge: true })
15
16
// Finally, once the user has been added,
17
// call the callback function from the props.
18
// 🚨if you forget to call this function, the app won't re-render
19
onUserAddedToDb()
20
}
21
22
return (
23
<View style={styles.container}>
24
<TextInput
25
placeholder="Enter your name"
26
value={name}
27
onChangeText={setName}
28
/>
29
<Button
30
title="Submit name"
31
onPress={handleSubmit}
32
/>
33
</View>
34
)
35
}
36
37
export default Onboarding
38
39
const styles= StyleSheet.create({
40
container: {
41
flex: 1,
42
justifyContent: 'center'
43
}
44
})
Copied!

4. (Bonus) Create <AfterAuth />

Here's an example app screen, which you can make in your AfterAuth.tsx file:
1
import React from 'react'
2
import {
3
Page,
4
ScreenBackground,
5
useDoormanUser,
6
H1,
7
Paragraph,
8
} from 'react-native-doorman'
9
import { Button } from 'react-native'
10
11
const AfterAuth = () => {
12
const { uid, signOut } = useDoormanUser()
13
return (
14
<Page
15
style={{ marginTop: 100, alignItems: 'center' }}
16
background={() => <ScreenBackground />}
17
>
18
<H1 style={{ color: 'white' }}>Welcome to Doorman.</H1>
19
<Paragraph style={{ color: 'white' }}>
20
Sign out below, if {`you'd`} like. Your user id is {uid}.
21
</Paragraph>
22
<Button title="Sign Out" color="white" onPress={signOut} />
23
</Page>
24
)
25
}
26
27
export default AfterAuth
28
Copied!

5. If you're using Firestore

If you're using Firestore as your DB, you'll find examples in this tutorial for how to read and write a user.
For the sake of the tutorial, you can create a db.ts file, and populate it with this. You can also set a custom firebaseConfig from your own Firebase project.
1
import firebase from 'firebase/app'
2
3
export const firebaseConfig = {
4
apiKey: 'AIzaSyCn8HyP1tVZiagk-YvZRwjSwKdwQw5Pvng',
5
authDomain: 'tester-9d8bb.firebaseapp.com',
6
databaseURL: 'https://tester-9d8bb.firebaseio.com',
7
projectId: 'tester-9d8bb',
8
storageBucket: 'tester-9d8bb.appspot.com',
9
messagingSenderId: '760778283392',
10
appId: '1:760778283392:web:05cb35d0837c93c6584965',
11
}
12
13
export const db = !firebase.apps.length
14
? firebase.initializeApp(firebaseConfig).firestore()
15
: firebase.app().firestore()
16
Copied!
Last modified 8mo ago