Using ReactFire with Ionic Framework & Capacitor

Image for post
Image for post

You should know that Reactfire is not considered “Production”

Overview

Required

you must create a file called src/env.js and add the following code

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.

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 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.

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;
// 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

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.
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

Written by

DC based software agency utilizing #Javascript, #Typescript, #HTML5, #Ionicframework, #NodeJS, #Firebase to build web & mobile solutions. https://buff.ly/300Zru

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store