Using ReactFire with Ionic Framework & Capacitor
Tags: firebase, react, ionic, javascript
Published: 2020-07-21 15:22:29


####[🔆Click Here for Ionic Framework ReactJS and VueJS Tips/Tutorials?🔆](https://buff.ly/35bAMIf) 

Sample project motivated by [video by David East](https://www.youtube.com/watch?v=cyQW2leJBnI) on [Reactfire](https://github.com/FirebaseExtended/reactfire)

> **You should know that [Reactfire](https://github.com/FirebaseExtended/reactfire) is not considered "Production"**

###Overview
- This project has been tested for use on mobile devices using [Capacitor](https://capacitorjs.com/) on IOS and Android
- In this project I use [Reactfire](https://github.com/FirebaseExtended/reactfire), [Ionic Framework ReactJS Components](https://ionicframework.com/react) and [React-Hook-Form](https://react-hook-form.com/).
- Currently there is only [Login](https://github.com/aaronksaunders/ionic-react-hook-form-react-fire/blob/master/src/pages/Login.tsx) and [Listing The Data Collection](https://github.com/aaronksaunders/ionic-react-hook-form-react-fire/blob/master/src/pages/Home.tsx)
- We use the `<AuthCheck/>` component for cleaner routing when not logged in, See [App.tsx](https://github.com/aaronksaunders/ionic-react-hook-form-react-fire/blob/master/src/App.tsx)
- Will be adding create user, add items and delete items

### Required
you must create a file called `src/env.js` and add the following code
```javascript
export const FIREBASE_CONFIG = {
// YOUR FIREBASE CONFIGURATION
};

// NAME OF COLLECTION IN FIREBASE TO LIST
export const FIREBASE_COLLECTION_NAME = "users"

// THIS IS REQUIRED FOR ANDROID
// SEE - https://github.com/FirebaseExtended/reactfire/issues/228
global.globalThis = window;
```

### Code Snippets

#### Checking Authentication Status At Startup
Here is the app it is much cleaner to check auth status and redirect the user appropriately, all of the listening for authChangeStatus and such is all gone...

If the authCheck fails, then we use the `Login` component.
```react
const App: React.FunctionComponent = () => {
  return (
    <FirebaseAppProvider firebaseConfig={FIREBASE_CONFIG}>
      <IonApp>
        <IonReactRouter>
          <IonRouterOutlet>
            <Suspense fallback={<IonLoading isOpen={true} />}>
              <AuthCheck fallback={<Login />}>
                <Home />
              </AuthCheck>
            </Suspense>
          </IonRouterOutlet>
        </IonReactRouter>
      </IonApp>
    </FirebaseAppProvider>
  );
};
```
#### Logging The User In
This is a 'hack' that is currently needed to address issues with clearing information between authenticated sessions. As stated above, this is not production ready code.

This code was pulled from the [issue in github](https://github.com/FirebaseExtended/reactfire/issues/228) where a work around was presented.

I found that this work around did not work on the android browser because the `globalThis` object was undefined. To resolve this issue, I set `globalThis` to `window` in the `env.js` file.

```javascript
export const FIREBASE_CONFIG = {
// YOUR FIREBASE CONFIGURATION
};

// NAME OF COLLECTION IN FIREBASE TO LIST
export const FIREBASE_COLLECTION_NAME = "users"

// THIS IS REQUIRED FOR ANDROID
// SEE - https://github.com/FirebaseExtended/reactfire/issues/228
global.globalThis = window;
```

```react
  // SEE - https://github.com/FirebaseExtended/reactfire/issues/228
  useEffect(() => {
    let map = (globalThis as any)["_reactFirePreloadedObservables"];
    map &&
      Array.from(map.keys()).forEach(
        (key: any) => key.includes("firestore") && map.delete(key)
      );
  }, []);
```
Here we use the `useAuth` hook to get the auth object to call the `signInWithEmailAndPassword` method
```react
  const auth = useAuth();
  /**
   * get data from form and sign the user in
   */
  const signIn = async (data: any) => {
    try {
      let r = await auth.signInWithEmailAndPassword(data.email, data.password);
      console.log(r);
    } catch (e) {
      setShowErrorAlert(e.message);
    }
  };
```
#### Rendering A Collection from the Database
- use the `useAuth` hook to get auth object for logging the user out.
- use the `useFirebaseApp` hook to get firebaseApp collection
- use the `useFirestoreCollectionData` to get the data collection to render.
```react
const Home: React.FunctionComponent = () => {
  const auth = useAuth();
  const thingsRef = useFirebaseApp()
    .firestore()
    .collection(FIREBASE_COLLECTION_NAME);
  const data = useFirestoreCollectionData(thingsRef, { idField: "id" });

  return (
    <IonPage>
      <IonHeader>
        <IonToolbar color="light">
          <IonButtons slot="end">
            <IonButton onClick={() => auth.signOut()}>Logout</IonButton>
          </IonButtons>
          <IonTitle>Home</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent className="ion-padding">
        <AuthCheck fallback={<IonLoading isOpen={true} />}>
          <IonList>
            {data.map((e: any) => {
              return (
                <IonItem key={e.id}>
                  <IonLabel className="ion-text-wrap">
                    {JSON.stringify(e)}
                  </IonLabel>
                </IonItem>
              );
            })}
          </IonList>
        </AuthCheck>
      </IonContent>
    </IonPage>
  );
};
```
### Whats Next
- Add Items Using Ionic Modal
- Delete Items using IonSlidingItem
- Create Account

### Source Code
{% github aaronksaunders/ionic-react-hook-form-react-fire %}

### See Other Work On My YouTube Channel
- https://www.youtube.com/channel/UCMCcqbJpyL3LAv3PJeYz2bg