13

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,602
  • 3
  • 20
  • 36
  • 1
    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

5 Answers5

19

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'
}),

Update 16-06-2022: That documentation page has been fixed and now uses addDoc() instead of setDoc() and collection() instead of doc().

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
1
[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
  • 139
  • 1
  • 5
1

I got the same problem and found a solution after many trials and errors, so decided to post the answer: the problem is lies in the doc reference. Firebase requires changing references: collection / document / collection / document, etc. In my case I was referencing collection/document/document and that gave me this error.

wrong way:

setDoc(doc(db, "collectionName", userID, documentID), ...

fixed (adding another collection in between):

setDoc(doc(db, "collectionName", userID, "anotherCollectionName", documentID), ...
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 Ribeiro
  • 1,844
  • 1
  • 18
  • 30
0

The discussion were started long ago but i know the problem and no one gave that answer, so i would write. The problem is: "doc()" function expect to take two arguments. First argument is the collection reference(example: collection(db, "i am a collection") ), second argument is the id of the document which you want to pick.

For Example:

let firestore = getFirestore();

let colref = collection(firestore, "i am a collection");

let document = doc(colref, "id of the document");

So for your example: the "doc()" function already taken the collection name from your "citiesRef" variable. You shouldn't put 3 arguments unless you don't want to put your "citiesRef"s arguments inside to the "doc()" function's arguments.

Necoo33
  • 11
  • 3