52

I'm trying to insert a document into a collection. I want the document to have a attribute of type reference to insert into the collection. But every time I insert into the collection, it comes out as a string or an object. How can I programmatically insert a reference typed value?

enter image description here


It's definitely possible to do it in the UI:

enter image description here

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
AskYous
  • 4,332
  • 9
  • 46
  • 82

5 Answers5

90

Probably the simplest solution is to set the value of a reference key to a doc(collection/doc_key) because a DocumentReference is needed.

Example code:

post = {
  content: "content...",
  title: "impressive title",
  user: db.doc('users/' + user_key),
};

db.collection('posts').add(post)
nVitius
  • 2,024
  • 15
  • 21
trojek
  • 3,078
  • 2
  • 29
  • 52
14

I was trying to figure this out today and the solution I came to was to use the .doc() to create a doc reference

  firebase.firestore()
    .collection("applications")
    .add({
      property: firebase.firestore().doc(`/properties/${propertyId}`),
      ...
    })

This will store a DocumentReference type on the property field so when reading the data you will be able to access the document as so

  firebase.firestore()
    .collection("applications")
    .doc(applicationId)
    .get()
    .then((application) => {
      application.data().property.get().then((property) => { ... })
    })
Phillip Boateng
  • 1,111
  • 1
  • 12
  • 16
  • is that property field is DocumentReference or String in model? – EngineSense Mar 29 '21 at 09:09
  • This doesn't seem to work for me though. I still get the error `ERROR FirebaseError: Function addDoc() called with invalid data` and if I just set the string it stores, meaning that this object/line of code causes this error. I tried adding `.ref` to cast it to a DocumentReference but now it doesn't seem to execute at all. – Ruben Szekér May 01 '21 at 10:57
5

This is the model class to store in firestore.

import { AngularFirestore, DocumentReference } from '@angular/fire/firestore';

export class FlightLeg {
  date: string;
  type: string;

  fromRef: DocumentReference; // AYT Airport object's KEY in Firestore
  toRef: DocumentReference;   // IST  {key:"IST", name:"Istanbul Ataturk Airport" }
}

I need to store FlightLeg object with reference value. In order to do this:

export class FlightRequestComponent {

  constructor(private srvc:FlightReqService, private db: AngularFirestore) { }

  addFlightLeg() {
    const flightLeg = {
      date: this.flightDate.toLocaleString(),
      type: this.flightRevenue,
      fromRef: this.db.doc('/IATACodeList/' + this.flightFrom).ref,
      toRef: this.db.doc('/IATACodeList/' + this.flightTo).ref,
    } as FlightLeg
    .
    ..
    this.srvc.saveRequest(flightLeg);
  }

The service which can save the object with referenced to another object into firestore:

export class FlightReqService {
   .
   ..
   ...
  saveRequest(request: FlightRequest) {
    this.db.collection(this.collRequest)
           .add(req).then(ref => {
              console.log("Saved object: ", ref)
           })
   .
   ..
   ...
  }
}
uzay95
  • 16,052
  • 31
  • 116
  • 182
3

The value of the field must be of type DocumentReference. It looks like you're putting some other object in there that has a property called id that's a string.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • 1
    Do I have to implement all those fields and functions? – AskYous Jul 11 '18 at 18:58
  • When working with the Firestore JavaScript SDK, you naturally work with those objects. Whatever AngularFire does must be wrapping that object. You'll have to get a hold of the underlying DocumentReference. – Doug Stevenson Jul 11 '18 at 18:59
  • Thanks! I just set the value to the DocumentReference that was returned form a query: https://i.imgur.com/MIY5HFU.png – AskYous Jul 11 '18 at 21:02
  • @AskYous : that is a useful image. it should be working up into the queston. (with text not an image) – James A Mohler Jul 11 '18 at 21:05
  • @DougStevenson, I now need to perform a `where` query on a field that's of type `reference`. Is that possible? If it's complicated, I can make another stackoverflow question. – AskYous Jul 12 '18 at 21:03
  • If you have a followup question that's different than the first, you should definitely ask it separately. – Doug Stevenson Jul 12 '18 at 21:45
  • You can import DocumentReference like this: import * as firebase from 'firebase/app'; export interface Message { text: string; userReference: firebase.firestore.DocumentReference; } – grrigore Apr 20 '19 at 20:44
0

It seems there may have been a recent update that has made the above answers outdated now. Funnily enough, the solution is even easier now. They've removed the .ref option, but the ref is automatically gotten now.

So you can just do:

const member = this3.$Firestore.doc('users/' + user2.user.uid);
this3.$Firestore.collection('teams').doc(this3.teamName).set({
  name: this3.teamName,
  members: [member],
});

Where member is the doc reference, simple as that. (Ignore the this3 lol.)

Matt Ke
  • 3,599
  • 12
  • 30
  • 49