I’m trying to get all the events from Firestore with this function:
import { db } from "../firebase";
import { collection, query, getDocs, where } from "firebase/firestore";
import getCurrentUser from "./CurrentUser";
const getEvents = async () => {
const uid = getCurrentUser().uid;
const eventsRef = collection(db, "events", uid);
const que = query(eventsRef, where("creator", "==", uid));
const result = await getDocs(que);
return result;
};
export default getEvents;
And I get error: "FirebaseError: Invalid collection reference. Collection references must have an odd number of segments, but events/98HobTnfjndUE1jIBQpKYCeN4hl2 has 2."
These are the rules of the database:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /events/{userId} {
allow read, update, delete: if request.auth != null && request.auth.uid == userId;
allow create: if request.auth != null;
}
}
}
What am I doing wrong? I found those rules from https://firebase.google.com/docs/firestore/security/rules-conditions. If I delete request.auth.uid == userId, it’s working but i want to keep it. So how can I make this function work? Thanks.
>Solution :
The error message you’re seeing is because Firestore expects an odd number of path segments when specifying a document or collection. In Firestore, paths alternate between collections and documents. For instance:
events
is a collectionevents/<some-id>
is a document in theevents
collectionevents/<some-id>/subcollection
is a subcollection under that document
You are currently trying to get a subcollection under a document in the events
collection with the UID as the name of the subcollection:
const eventsRef = collection(db, "events", uid);
But, based on your Firestore rules and the error you’re encountering, it seems you’re trying to get a document with the UID, not a subcollection.
Here’s how you can fix your code:
- Modify the Firestore Reference
Change your getEvents
function to get the document with UID:
const getEvents = async () => {
const uid = getCurrentUser().uid;
const eventDocRef = doc(db, "events", uid);
const result = await getDoc(eventDocRef);
return result;
};
- Check Firestore Data Structure
Ensure that your Firestore database structure matches what you’re trying to query. If you’re using the UID as a document ID inside the events
collection, then the above change should work. However, if you intended to have a subcollection under each user document, then your database structure would need a revision to match your querying logic.
- Firestore Rules
Your rules seem to be focused on user-specific documents in the events
collection. Ensure that each user’s data is stored as a document with their UID as the document ID in the events
collection.