Nuxt - Behaviour of Fetch lifecycle hook on page refresh

Viewed 1445

I am not sure if this is expected behaviour, but in short, I have/ had a problem where my Universal-mode Nuxt app could not read from Firebase following a refresh of the page. This is because the request came from the server and therefore was being seen by Firebase as an unauthenticated user. I worked around it by forcing SPA mode on the affected page, and it works, but I don't like it as a solution.

Reason this happened is that I was/ am using the Firebase client library (So making the call from the client). I am using Nuxt's fetch() hook to invoke the read action. I used the client library as I (perhaps naively) assumed that this was better for page performance.

To stop refresh failing I should be (I believe) appending fetchOnServer: false to the fetch hook as per the Nuxt docs.

However this does not solve the issue.

I suspect this is because a refresh is not invoking Nuxt/ Vue functions in the same way as navigating to the page via the Nuxt router does. Is this correct? (I can see even with fetchOnServer set to False fetch() still causes server- side requests to Firebase, which fail, as expected). Is there another way around this other than forcing SPA on the page as above? If not, I may look at using the Firebase-Admin library.

Appreciate any feedback on this.

EDIT: Here is an example query I am running in SPA mode currently - this returns all events that a given user is allowed to access. The result is returned to Vuex for client rendering of course :)

  async getListOfEvents(uid) {
    fireDb = firebase.firestore()
    await firebase.auth().currentUser
    const pList = fireDb
      .collection('presentations')
      .where('usersWithPerms', 'array-contains', uid)
      .where('status', '==', 'ACTIVE-VISIBLE')
    try {
      const messageDoc = await pList.get()
      const aVP = []
      let rObj = {}
      messageDoc.forEach(function (childSnapshot) {
        const o = childSnapshot.data()
        rObj.pName = o.eventName
        rObj.synopsis = o.synopsis
        rObj.urlSlug = o.urlSlug
        rObj.owner = o.owner === uid
        aVP.push(rObj)
        rObj = {}
      })
      return aVP
    } catch (e) {
      console.log(`Error during getting LIST of events! ${e}`)
    }
  },```
2 Answers

I don't know if I completely understand your problem, but I imagine that you want to fetch the data from firebase just on the client on a specific page.

So, you could do this: Call your method on some vue lifeCycle method like created() or mounted() and add process.browser validation. Something like that:

created() {
  if (process.browser) {
    // fetch from firebase
  }
}

So in the end the cleanest way to get around this was to just go ahead and use 'Nuxt Firebase' https://firebase.nuxtjs.org/guide/getting-started/

It requires a Service Worker and therefore Nuxt PWA to work properly, but the results are very satisfactory.

I am also not a huge fan of the fact the Firebase services you enable are within global scope using this, but so far I have found very little negative impact on app performance. (Running tests via Lighthouse)

Related