This repository is an Expo/React-Native project that uses a simple, reusable pattern for connecting to Firebase services and leveraging Firebase Authentication and Firestore for user registration, login, logout and "dynamically watching" user profile data in real-time.
In this project we show:
- Firebase Authentication: register user, login and logout
- Firestore database: for storing and retrieving "user profile" data with realtime updates
- Expo Router: for navigation and protected routes requiring a logged-in user
This project was created with npx create-expo-app
. It uses Expo Router for navigation, and Firebase for Auth and Firestore Database.
NOTE: minimal time was spent on styling in order to focus on Firebase functionality, so the UI is extremely basic (ie: ugly).
NOTE #2: This is a peer project to react-and-user-profiles-with-firebase-auth-and-firestore. The goal is to have the two providers (FirebaseProvider
and AuthProvider
) be nearly identical in both projects.
This component configures the app with your Firebase project's configuration information (the firebaseConfig), and gets the various Firebase services available for the rest of the app to use. The component uses React's Context API to make the services available. The firebaseConfig
is stored in a JSON file in the src/providers
folder; details below.
This component uses the Firebase Auth service (it gets from the <FirebaseProvider />) to enable the AuthStateChanged listener, makes available functions: login()
, logout()
and register()
, upon successful registration stores "user profile" data to Firestore, and upon a successful login fetches the "user profile" data for the currently logged in user.
git clone https://github.com/gregfenton/expo-and-user-profiles-with-firebase-auth-and-firestore.git
cd expo-and-user-profiles-with-firebase-auth-and-firestore
npm install expo@latest
to install Exponpx expo install
to install the remaining NPM dependencies- Open your favourite code editor (e.g.
code .
to run VSCode on this project) - Ensure your Firebase project has enabled the Email/Password sign-in provider:
- Firebase Console >> YOUR_PROJECT >> Authentication >> Sign-In Method
- If "Email/Password" is not listed under Sign-In Providers, click Add New Provider and add it
- Ensure that Email/Password is Enabled
- Ensure your Firebase project has enabled the Firestore Database:
- Firebase Console >> YOUR_PROJECT >> Firestore Database
- if you see a Create Database button, click it
- if prompted for Security Rules, choose to go with test mode for now
- Copy the file
providers/firebaseConfig.json.example
toproviders/firebaseConfig.json
- Edit the file
providers/firebaseConfig.json
and replace the file's contents with your Firebase project's configuration (see initial contents of the JSON file for instructions) npm run start
to start the Expo development server- Once started, click
i
to start the iOS simulator,a
to start the Android emulator,w
to open the web browser, orq
to quit the Expo CLI
In the running app:
- If you have an existing account in your Firebase Authentication the enter the email, password and click the Login button.
- If you'd like to register a new account, click the Register button.
- Once logged in, you will be presented with the
displayName
andemail
values that are in Firestore >>users
>> [the UID from Firebase Auth]
You might also keep the "Welcome!" page showing and use Firebase Console >> Firestore to change the displayName
of the user document. You will see the Expo app update its UI in real-time.
The main parts of this app that is reusable are FirebaseProvider
and AuthProvider
, both located in src/providers
.
To use them, copy these two files into your Expo app, and somewhere near the top of your app's component tree "wrap" the parts of your app you want to use Firebase in with these two providers. In this project, the wrapping happens in app/(app)/_layout.tsx
:
return (
<FirebaseProvider>
<AuthProvider>
<RootLayoutNav />
</AuthProvider>
</FirebaseProvider>
);
where <RootLayoutNav />
represents the rest of your app's Expo Router configuration.
Then in components <RootLayoutNav />
or its descendants you can use the hooks:
useFirebaseContext()
to access the various handles to Firebase services:myApp
,myAuth
,myFS
,myStorage
and emulator settingsusingEmulators
andemulatorsConfig
.useAuthContext()
to access thelogin()
,logout()
andregister()
functions, theprofile
object that contains thedisplayName
andemail
values from the user's Firestore "user profile" document, and theuser
object from Firebase Auth that is set when the user login process completes successfully (i.e. it is set by the onAuthStateChanged() listener)