skip to Main Content

I’m trying to use the VueUse useFirestore() wrapper.

It returns a ref that is in sync with a Firestore document.

Currently I can use it to get and display a users doc.

But now I need to get and display a websites doc by referencing a currentWebsiteId field from the users doc.

When I try to do that, nothing is displayed. There are no errors in the console either.

This is what my code looks like:

<template>
  <div>{{ user }}</div> 
  <div>{{ website }}</div>
</template>

<script setup lang="ts">
import { useAuth } from '@vueuse/firebase/useAuth';
import { useFirestore } from '@vueuse/firebase/useFirestore';
import { doc } from 'firebase/firestore';
import { auth, db } from 'src/config/firebase';
import { User, Website } from 'src/types';

const { user: authUser } = useAuth(auth);

const userDocRef = doc(db, `users/${authUser.value?.uid}`);
const user = useFirestore<User>(userDocRef);

const websiteDocRef = doc(db, `websites/${user.value?.currentWebsiteId}`);
const website = useFirestore<Website>(websiteDocRef);
</script>

Since useFirestore() is asynchronous it will initially return undefined before shortly after returning the actual Firestore document.

I thought this could be the issue, so I tried using a watch to get around that like so:

let website = ref();
watch(user, () => {
  const websiteDocRef = doc(db, `websites/${user.value?.currentWebsiteId}`);
  website = useFirestore<Website>(websiteDocRef);
});

But that also has the same problem. Nothing is nothing is displayed, and there are no errors in the console either.

2

Answers


  1. Chosen as BEST ANSWER

    As commented by @EstusFlask, the docs show that it needs to be wrapped in a computed ref.

    This is because computed gets recalculated when any of it's ref values change.

    Therefore websiteDocRef becomes this:

    const websiteDocRef = computed(() =>
      doc(db, `websites/${user.value?.currentWebsiteId}`)
    );
    

    Here is the full code:

    <template>
      <div>{{ user }}</div> 
      <div>{{ website }}</div>
    </template>
    
    <script setup lang="ts">
    import { useAuth } from '@vueuse/firebase/useAuth';
    import { useFirestore } from '@vueuse/firebase/useFirestore';
    import { doc } from 'firebase/firestore';
    import { auth, db } from 'src/config/firebase';
    import { User, Website } from 'src/types';
    
    const { user: authUser } = useAuth(auth);
    
    const userDocRef = doc(db, `users/${authUser.value?.uid}`);
    const user = useFirestore<User>(userDocRef);
    
    const websiteDocRef = computed(() =>
      doc(db, `websites/${user.value?.currentWebsiteId}`)
    );
    const website = useFirestore<Website>(websiteDocRef);
    </script>
    

  2. As commented by @Estus Flask, website = useFirestore – this is a mistake, never reassign refs, only their values. Composables are supposed to be used directly in setup, by calling it multiple times you most likely misuse it. Wrap doc() that depends on currentWebsiteId with a computed. It’s already explained in docs, vueuse.org/firebase/usefirestore/#usage

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search