Search code examples
angularfire2

Firestore's WriteBatch.update() won't take angularfirestore2's AngularFirestoreDocument


I'm trying to do a batch write using Firestore's WriteBatch. I'm trying to add updates to the WriteBatch and that requires a DocumentReference. I have a AngularFirestoreDocument and can't figure out how to cast that to a DocumentReference and get it to compile or run correctly.

I've tried to cast it to any,unknown, and DocumentReference and use the AngularFirestoreDocument as is.

export class FinancialService {
    private transCollection: AngularFirestoreCollection<Transaction>;

    batch_update_trans(trans) {
        let writer = this.afs.firestore.batch();
        this.transCollection = this.afs.collection<Transaction>('balance_sheets/'+this.balance_sheet_id+"/transactions/");
        for (let t of trans) {
          writer.update(this.transCollection.doc(id),t);
        }
        return writer.commit();
    }
}

if I include the AngularFirestoreDocument as is like above I get this compile time error: error TS2345: Argument of type 'AngularFirestoreDocument<{}>' is not assignable to parameter of type 'DocumentReference'. Type 'AngularFirestoreDocument<{}>' is missing the following properties from type 'DocumentReference': id, firestore, parent, path, and 2 more.

If I cast the AngularFirestoreDocument to a DocumentReference: writer.update(<DocumentReference>this.transCollection.doc(id),t);

I get this compile time error: error TS2352: Conversion of type 'AngularFirestoreDocument<{}>' to type 'DocumentReference' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Type 'AngularFirestoreDocument<{}>' is missing the following properties from type 'DocumentReference': id, firestore, parent, path, and 2 more

If I cast the AngularFirestoreDocument to a DocumentReference to unknown: writer.update(<unknown> this.transCollection.doc(id),t); It fails to compile with this error: error TS2345: Argument of type 'unknown' is not assignable to parameter of type 'DocumentReference'.

If I cast the AngularFirestoreDocument to a DocumentReference to any: writer.update(<any> this.transCollection.doc(id),t); it does compile, but I get a runtime error when I try go batch update docs this way: Uncaught (in promise): FirebaseError: [code=invalid-argument]: Function WriteBatch.update() requires its first argument to be a DocumentReference, but it was: an object FirebaseError: Function WriteBatch.update() requires its first argument to be a DocumentReference, but it was: an object

I was expecting the code to compile and successfully batch update Transaction docs.


Solution

  • OK, I figured out how to do this using this really helpful article that provides a lot of documentation that angularfire2 doesn't have itself: Firestore Advanced Usage : angularfire - atomic writes

    You can access the javascript API through angularfire2's firestore module and create a DocumentRef through that API, instead of using angularfire2's AngularFirestoreDocument type.

    The working code looks like this:

    export class FinancialService {
    
        batch_update_trans(trans) {
            let writer = this.afs.firestore.batch();
            let transDoc = null;
            for (let t of trans) {
              transDoc = this.afs.firestore.doc(
                 'balance_sheets/'+this.balance_sheet_id+"/transactions/"+t.id);
              writer.update(transDoc,t);
            }
            return writer.commit();
        }
    }