I have a Firestore users
doc that looks something like this:
{
currentCompanyId: "123",
displayName: "Mary Jane"
}
And a Firestore websites
doc that looks something like this:
{
companyId: "123",
homePageUrl: "https://www.google.com/"
}
Now I'm trying to use the VueUse useFirestore() wrapper to display the websites
doc.
To do that I am referencing the currentCompanyId
property of the users
doc inside a where
Query Constraint like so:
<template>
<div>
{{ websites?.[0] }}
</div>
</template>
<script setup lang="ts">
import { useAuth } from '@vueuse/firebase/useAuth';
import { useFirestore } from '@vueuse/firebase/useFirestore';
import { collection, doc, query, where } from 'firebase/firestore';
import { auth, db } from 'src/config/firebase';
import { User } from 'src/types';
import { computed } from 'vue';
const { user: authUser } = useAuth(auth);
const userDocRef = doc(db, `users/${authUser.value?.uid}`);
const user = useFirestore<User>(userDocRef);
const websiteQuery = computed(() =>
query(
collection(db, 'websites'),
where('companyId', '==', user.value?.currentCompanyId) // This produces an error
// where('companyId', '==', '123') // This works, but is not practical
)
);
const websites = useFirestore(websiteQuery);
</script>
Hard-coding the companyId
value of 123
works.
But whenever I use user.value?.currentCompanyId
inside the computed ref it throws an error saying this:
TypeError: right-hand side of 'in' should be an object, got null
I figured it out.
The problem was that user.value?.currentCompanyId
is initially null
.
Here is the error message again:
TypeError: right-hand side of 'in' should be an object, got null
It's basically saying the right-hand side of the Where
query constraint should be an object, but it got null.
Wrapping the query in a computed
ref will eventually change the value from null
into something else when it updates. But initially it is null
. And that is the cause of the error.
To overcome this problem you can set some initial properties of user
in the useFirestore
. So the Where
query constraint will use that non-null value initially. Even an empty string will be ok. You can use anything that is not null
.
Here is the full code:
<template>
<div>
{{ websites?.[0] }}
</div>
</template>
<script setup lang="ts">
import { useAuth } from '@vueuse/firebase/useAuth';
import { useFirestore } from '@vueuse/firebase/useFirestore';
import { collection, doc, query, where } from 'firebase/firestore';
import { auth, db } from 'src/config/firebase';
import { User } from 'src/types';
import { computed } from 'vue';
const { user: authUser } = useAuth(auth);
const userDocRef = doc(db, `users/${authUser.value?.uid}`);
const user = useFirestore<User>(userDocRef, { currentCompanyId: '' }); // <-- See change here
const websiteQuery = computed(() =>
query(
collection(db, 'websites'),
where('companyId', '==', user.value?.currentCompanyId)
)
);
const websites = useFirestore(websiteQuery);
</script>