AndreTeixeira1998 / ReactNative-Expo-Firebase-Boilerplate-v2

React Native Expo boilerplate with Firebase (Auth, Firestore, Storage). Push Notifications and Dark theme.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

React Native Expo with Firebase V2

Buy Me A Coffee

Screens

Demo

Try with Expo Go on your device. SDK 50.

Requirements

  • Node 18
  • Yarn 1.22.x
  • eas-cli
  • Expo Account

Infrastructure

  • React Native
  • Expo
  • Firebase(Authentication, Firestore, Cloud Storage)

Libraries

  • expo
  • firebase
  • axios
  • react-navigation
  • expo-constants
  • expo-image-manipulator
  • expo-image-picker
  • expo-notifications
  • react-native-elements
  • react-native-paper
  • react-native-svg
  • react-native-vector-icons
  • jotai
  • moment

Features

  • BottomTab, TopTab, Modal and Stack navigation
  • Registration with E-mail & Password
  • Login with E-mail and Password
  • Change password
  • Deleting an account
  • Handling persisted login credentials
  • Writing to Firestore Database
  • Reading from Firestore Database
  • Uploading images to Cloud Storage
  • Update user profile
  • Dynamic switching of dark themes by device appearance
  • Dynamic header title
  • Retrieving Expo push tokens and saving them to Firestore
  • State management by Jotai

Difference from v1

reactnative-expo-firebase-boilerplate v1

  • use Context API
  • Adjustment style file

How to use

Video guide(Japanese)

How to start video

1. Install

Download zip or click "Use this template"

or

git clone https://github.com/kiyohken2000/ReactNative-Expo-Firebase-Boilerplate-v2.git
cd ReactNative-Expo-Firebase-Boilerplate-v2
yarn install

2. Setting up Firebase

Step 1: Create a Google Firebase Account

  • Go to https://console.firebase.google.com/
  • Sign up an account and create a new project
  • Put in your project name, click "Continue".
  • Google Analytics can be enabled or disabled.
  • Click "Create Project" it is going to take a while before it says "Your new project is ready", click "Continue."

Step 2: Configure Firebase Console Sign-In Methods

  • On "Project Overview", click the "Authentication" on the left sidebar.
  • Click on the second tab where it said "Sign-In method"
  • Enable all the Sign-in method you would like to enable. For now, we will enable the "Email/Password" option.

Step 3: Configure Firebase Console Firestore

  • We will then click the "Cloud Firestore" on the left to create a database.
  • Select the "Start in test mode" option, click "next."
  • Select the "Cloud Firestore location", click "Enable"
  • Create the "users" and "tokens" collections. An empty document is fine.

Security Rules

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    function isLogin() {
      return request.auth.uid != null;
    }
    match /{document=**} {
      allow read, write: if isLogin();
    }
  }
}

Step 4: Create a folder in Cloud Storage

  • Next. Click Storage on the left.
  • Create an empty "avatar" folder.
  • Upload the image file "icon.png" of your choice. This is the default icon for app users.

Security Rules

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Step 5: Copy the API Key

  • On the Project Overview, click on the "Web" icon since we are building on Expo.
  • Then give it a name, click "Register app".
  • It will show you the Firebase configuration, copy the SDK keys, we will use it in the next step.

Step 6: Connect Firebase

  • Write the copied API Key in your app.

src\config.js

const firebaseKey = {
  apiKey: "Your API Key",
  authDomain: "Your API Key",
  projectId: "Your API Key",
  storageBucket: "Your API Key",
  messagingSenderId: "Your API Key",
  appId: "Your API Key",
  measurementId: "Your API Key"
};

3. Update app.json and app config

Replace the name and Slug with yours.

"name": "your-app-name",
"slug": "your-app-slug",

Remove expo.updates.url

"updates": {
  "enabled": true,
  "fallbackToCacheTimeout": 10000,
  "url": "https://u.expo.dev/1650611b-a5b8-4420-9656-60c06429edd4"
},

Remove expo.extra and expo.runtimeVersion

"extra": {
  "eas": {
    "projectId": "1650611b-a5b8-4420-9656-60c06429edd4"
  }
},
"runtimeVersion": {
  "policy": "appVersion"
}

src\config.js

const defaultAvatar = 'Your default icon URL'
const expoProjectId = 'Your project id'

If you do not have an Expo Project ID, run this command.

eas build:configure

Then check the expo.extra.projectId in app.json.

4. Run Your App

yarn start

How to use utils

  • Reload app

import { Restart } from '../../utils/Restart'

const ourFunc = async() => {
  await Restart()
}
  • Storage

import { storage } from '../../utils/Storage'

const saveStorage = async() => {
  const today = moment().toString()
  await storage.save({
    key: 'date',
    data: {
      'date': today
    }
  })
}

const loadStorage = async() => {
  try {
    const result = await storage.load({key: 'date'})
  } catch (e) {
    console.log(e)
  }
}

const removeStorage = async() => {
  await storage.remove({ key: 'date' })
}
  • Toast & Notification

// Toast
import { showToast } from '../../utils/ShowToast'

const onShowToastPress = () => {
  showToast({
    title: 'Hello',
    body: 'This is some something πŸ‘‹',
    isDark // true or false
  })
}

// Send Notification
import { sendNotification } from '../../utils/SendNotification'

const onNotificationPress = async() => {
  const res = await sendNotification({
    title: 'Hello',
    body: 'This is some something πŸ‘‹',
    data: 'something data',
    token: token.token //e.g. ExponentPushToken[WGSdXiJ5rLHAK53DRPq2x-]
  })
  console.log(res)
}
  • Snackbar

import React, { useState } from 'react'
import { View, StyleSheet } from 'react-native'
import ScreenTemplate from '../../components/ScreenTemplate'
import Button from '../../components/Button'
import ShowSnackbar from '../../components/ShowSnackbar' // import snackbar component

export default function Follower() {
  const [visible, setVisible] = useState(false) // create snackbar state

  const onDismissSnackBar = () => setVisible(false) // create hide snackbar function

  const onShowSnackbarPress = () => { // create show snackbar function
    setVisible(true)
  }

  return (
    <>
    <ScreenTemplate>
      <View style={styles.container}>
        <View style={{width:'100%'}}>
          <Button
            label='Show Snackbar'
            color={colors.purple}
            onPress={onShowSnackbarPress}
          />
        </View>
      </View>
    </ScreenTemplate>
    {/* Pass props to snackbar component */}
    <ShowSnackbar
      visible={visible}
      onDismissSnackBar={onDismissSnackBar}
      title='Hello πŸ‘‹'
      duration={3000}
    />
    </>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
})
  • Data fetch, Loading, Error

export default function Print() {
  const [data, setData] = useState([])
  const [isLoading, setIsLoading] = useState(false) // Create loading flag
  const [isError, setIsError] = useState(false) // Create error flag

  const fetchData = async() => {
    try {
      setIsLoading(true) // Set flag
      const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
      setData(data)
    } catch(e) {
      console.log('error', e)
      setIsError(true) // Set flag
    } finally {
      setIsLoading(false) // Set flag
    }
  }

  return (
    <ScreenTemplate isLoading={isLoading} isError={isError}> {/* Pass flag to ScreenTemplate component */}
      <ScrollView style={styles.main}>
        {data.map((item, i) => {
          return (
            <RenderItem item={item} key={i} index={i} />
          )
        })}
      </ScrollView>
    </ScreenTemplate>
  )
}

NOTES

  • getExpoPushTokenAsync()

The experienceId is required to get the push token using getExpoPushTokenAsync in the EAS build.

const token = await Notifications.getExpoPushTokenAsync({
  projectId: 'your project id'
});
  • .easignore

If you want to use environment variables in EAS build, create .easignore.

How projects are uploaded to EAS Build

Migrate to development build

If you want to use libraries that contain native code, you must use the development build.

Requirements

  • expo account
  • eas-cli

1. Install expo-dev-client

npx expo install expo-dev-client

2. Create eas.json and update eas.json

eas update:configure
eas build:configure

example

eas.json

{
  "cli": {
    "version": ">= 3.15.0"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "channel": "development",
      "ios": {
        "simulator": false
      }
    },
    "preview": {
      "distribution": "internal",
      "channel": "internal"
    },
    "production": {
      "channel": "production"
    }
  },
  "submit": {
    "production": {}
  }
}

3. Register iPhone in Ad Hoc and install profile on iPhone

eas device:create

4. Build your App and Install your App on your device

eas build --profile development --platform ios
eas build --profile development --platform android

5. Run

yarn start

Scan the QR code above with Expo Go (Android) or the Camera app (iOS)

Commands

// build: develop
eas build --profile development --platform ios
eas build --profile development --platform android

// build: internal
eas build --profile preview --platform ios
eas build --profile preview --platform android

// build: production
eas build --profile production --platform ios
eas build --profile production --platform android

// OTA update
eas update --channel internal --message "Updating the app"
eas update --channel production --message "Updating the app"

// iOS: Setting up ad hoc provisioning
eas device:create
// list all registered devices for your account
eas device:list

// Expo Settings
eas build:configure
eas update:configure

Licence

This project is available under the MIT license. See the LICENSE file for more info.

About

React Native Expo boilerplate with Firebase (Auth, Firestore, Storage). Push Notifications and Dark theme.

License:MIT License


Languages

Language:JavaScript 100.0%