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.
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();
}
}