Vue3 Firebase Composable Introduction w/ Ionic Framework
Tags: vue, ionic, javascript, tutorial
Published: 2020-11-30 18:21:16

[Firebase](https://firebase.google.com/) has come a long way and IMHO the API has gotten much easier to integrate into your applications even without third-party libraries. I was looking to do a video on integrating [vuefire](https://vuefire.vuejs.org/) and after poking around for a while I decided to start with the basics first and then maybe later show a [vuefire](https://vuefire.vuejs.org/) integration.

The whole project is a simple list/detail application in VueJS and [Ionic Framework](https://ionicframework.com/docs/vue/overview). We display the list, you can pull to refresh and you can click a list item to route to a detail page and load the user.

For the blog post, I am going over the `firebaseService` we create to access the data; the Ionic components are covered in the video linked below.


Setup the basic vue and firebase imports
```javascript
import { onMounted, ref } from "vue";

// FIREBASE
import firebase from "firebase/app";
import "firebase/firestore";

const db = firebase
  .initializeApp({ projectId: process.env.VUE_APP_FIREBASE_PROJECT_ID })
  .firestore();
```
Define the properties that are available to every instance of the service. Notice they are outside of the function definition. 
```javascript
// define the user collection once
const userCollection = db.collection("users");

// hold the users retrieved from the database
const users = ref<any>([]);

// any error from firebase call
const error = ref<any>(null);

// when we are loading
const loading = ref<any>(false);
```

Let's define the composable and the initial properties that we will be returning
```javascript
export default () => {

  return {
    //properties
    users,
    loading,
    error,
  };
}
```
### Getting All of the Users
To get all of the users from the firestore we can query the collection. This is the function to call using the collection const we created.
```javascript
  const getCollectionData = async (collection: any) => {
    loading.value = true;
    try {
      const querySnapshot = await collection.get();
      const results = querySnapshot.docs.map((doc: any) => {
        return { ...doc.data(), id: doc.id };
      });
      loading.value = false;
      return results;
    } catch (e) {
      error.value = e;
      loading.value = false;
    }
  };
```
Since we will be calling the function multiple times, `onMounted` and it is also used when refreshing the database I have created a helper function.
```javascript
export default () => {
  const getCollectionData = async (collection: any) => {
    loading.value = true;
    try {
      const querySnapshot = await collection.get();
      const results = querySnapshot.docs.map((doc: any) => {
        return { ...doc.data(), id: doc.id };
      });
      loading.value = false;
      return results;
    } catch (e) {
      error.value = e;
      loading.value = false;
    }
  };

  // helper
  const loadUsers = async () => {
    users.value = await getCollectionData(userCollection);
  };

  // when initialized, get all the users
  onMounted(async () => {
    await loadUsers();
  });

  return {
    // functions
    loadUsers,
    //properties
    users,
    loading,
    error,
  };
};
```
### Getting A Specific User
There are two ways to get a specific user, from the local array/cache `users` or to call the firestore database again.
```javascript
  /**
   * get the user from the local array
   * @param userId
   */
  const getLocalUser = (userId: string) => {
    return users.value.find((u: any) => u.id === userId);
  };
```
If we want to get the data from the database
```javascript
  /**
   * get the document from firebase and not local users
   * 
   * @param collection 
   * @param id 
   */
  const getCollectionDoc = async (collection: any, id: string) => {
    loading.value = true;
    try {
      const doc = await collection.doc(id).get();
      loading.value = false;
      return { ...doc.data(), id: doc.id };
    } catch (e) {
      error.value = e;
      loading.value = false;
    }
  };
```
to make this function more accessible, we have added a helper function to
```javascript
getUser : (id: string) => getCollectionDoc(userCollection,id),
```
### Wrap Up
This was just a quick overview of the code for the firebase composable; there is more detail and explanation in the @youtube video attached below.

If you have any questions, feel free to leave a comment here or on the video.

This is the source code for the project that I walk thru the process of developing a firebase composable to access collections and documents. 


#### Watch Me Code in the youtube video.
{% youtube -pFu52HCd20 %}
#### Full Project Source Code
{% github aaronksaunders/vue3-firebase-composable1 %}

[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/W7W31U7HM)