5

Hello I am following the firestore tutorial here

https://firebase.google.com/docs/firestore/query-data/queries#web-version-9_14

First they instruct me to seed the database with

import { collection, doc, setDoc } from "firebase/firestore"; 

const citiesRef = collection(db, "cities");

await setDoc(doc(citiesRef, "SF"), {
    name: "San Francisco", state: "CA", country: "USA",
    capital: false, population: 860000,
    regions: ["west_coast", "norcal"] });
await setDoc(doc(citiesRef, "LA"), {
    name: "Los Angeles", state: "CA", country: "USA",
    capital: false, population: 3900000,
    regions: ["west_coast", "socal"] });
await setDoc(doc(citiesRef, "DC"), {
    name: "Washington, D.C.", state: null, country: "USA",
    capital: true, population: 680000,
    regions: ["east_coast"] });
await setDoc(doc(citiesRef, "TOK"), {
    name: "Tokyo", state: null, country: "Japan",
    capital: true, population: 9000000,
    regions: ["kanto", "honshu"] });
await setDoc(doc(citiesRef, "BJ"), {
    name: "Beijing", state: null, country: "China",
    capital: true, population: 21500000,
    regions: ["jingjinji", "hebei"] }); 

Later in the tutorial they instruct me to run this code to create some subcollections

import { collection, doc, setDoc } from "firebase/firestore";  

const citiesRef = collection(db, 'cities');

await Promise.all([
    setDoc(doc(citiesRef, 'SF', 'landmarks'), {
        name: 'Golden Gate Bridge',
        type: 'bridge'
    }),
    setDoc(doc(citiesRef, 'SF', 'landmarks'), {
        name: 'Legion of Honor',
        type: 'museum'
    }),
    setDoc(doc(citiesRef, 'LA', 'landmarks'), {
        name: 'Griffith Park',
        type: 'park'
    }),
    setDoc(doc(citiesRef, 'LA', 'landmarks'), {
        name: 'The Getty',
        type: 'museum'
    }),
    setDoc(doc(citiesRef, 'DC', 'landmarks'), {
        name: 'Lincoln Memorial',
        type: 'memorial'
    }),
    setDoc(doc(citiesRef, 'DC', 'landmarks'), {
        name: 'National Air and Space Museum',
        type: 'museum'
    }),
    setDoc(doc(citiesRef, 'TOK', 'landmarks'), {
        name: 'Ueno Park',
        type: 'park'
    }),
    setDoc(doc(citiesRef, 'TOK', 'landmarks'), {
        name: 'National Museum of Nature and Science',
        type: 'museum'
    }),
    setDoc(doc(citiesRef, 'BJ', 'landmarks'), {
        name: 'Jingshan Park',
        type: 'park'
    }),
    setDoc(doc(citiesRef, 'BJ', 'landmarks'), {
        name: 'Beijing Ancient Observatory',
        type: 'museum'
    })
]); 

However, this results in the error

errors.ts:94 Uncaught FirebaseError: Invalid document reference. Document references must have an even number of segments, but cities/SF/landmarks has 3.

Anyone know what the reason for that is?

Boris Grunwald
  • 2,064
  • 1
  • 16
  • 28
  • This might be helpful too: [Firestore: What's the pattern for adding new data in Web v9?](https://stackoverflow.com/questions/68987326/firestore-whats-the-pattern-for-adding-new-data-in-web-v9/68987445#68987445). – Dharmaraj Feb 23 '22 at 19:26

3 Answers3

6

That looks like a mistake in the sample code. Since citiesRef is a collection reference, so is doc(citiesRef, 'SF', 'landmarks'), and you can't call setDoc on a collection reference.

Call addDoc instead of setDoc and collection instead of doc and things should work much better:

addDoc(collection(citiesRef, 'SF', 'landmarks'), {
    name: 'Golden Gate Bridge',
    type: 'bridge'
}),
Frank van Puffelen
  • 499,950
  • 69
  • 739
  • 734
0

I was having the same error, but still wanted to use the setDoc instead of addDoc.

Invalid document reference. Document references must have an even number of segments, but collection has 1.

The reason of my error was that when I called doc(db, 'collection', id) and the id was being an empty string ''.

I just added a check before, so that the collectionId is not undefined or empty string.

Here's my snippet:

export const addPlayedGame = async (collectionId: string) => {
  try {
    if(!collectionId) return false;

    const collectionRef = doc(firebase.db, 'collection', collectionId);

    const updateObject = {
     ...
    };

    await setDoc(collectionRef, updateObject, { merge: true });

    return true;
  } catch (error) {
    return false;
  }
};

Frederiko Cesar
  • 1,280
  • 13
  • 22
0
[setDoc]([doc](citiesRef, 'DC', 'landmarks'), {
    name: 'National Air and Space Museum',
    type: 'museum'
}),

change your setDoc to addDoc and your doc to collection this should address it. if your are referencing a collection don't used doc instead used collection

RaySun
  • 21
  • 3