Reputation: 2053
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
Upvotes: 1
Views: 286
Reputation: 2053
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>
Upvotes: 0
Reputation: 50840
Try passing the QueryConstraint
only when the value is defined like this:
const websiteQuery = computed(() => {
const queryContraints: any = [];
const currentCompanyId = user.value?.currentCompanyId;
if (currentCompanyId) queryContraints.push(where("companyId", "==", currentCompanyId));
return query(
collection(db, 'websites'),
...queryContraints
)
});
This however will return all documents if you don't provide the where()
constraint so maybe try running query only when this is defined i.e. after the auth state has loaded. onAuthStateChanged()
might be useful here.
Upvotes: 1