FirebaseError: Invalid collection reference. Collection references must have an odd number of segments

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 collection
  • events/<some-id> is a document in the events collection
  • events/<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:

  1. 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;
};
  1. 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.

  1. 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.

Leave a Reply