Reputation: 1405
I am trying to implement Repository Pattern with Firestore Firebase and TypeScript.
Code:
import { firestore } from "firebase-admin";
import { ISearchCriteria } from './ISearchCriteria'
//export class selectQuery<T> {
// constructor(private query: firestore.Query<T>) { }
//}
export class DBContext {
static current: DBContext = new DBContext();
private db: firestore.Firestore;
private constructor() {
this.db = firestore();
}
collection(collectionName: string): firestore.CollectionReference<firestore.DocumentData> {
return this.db.collection(collectionName);
}
public async where<T extends object>(collectionName: string, searchCriteria: ISearchCriteria[]): Promise<T[]> {
var snapShot = this.collection(collectionName);
for (var i = 0; i < searchCriteria.length; i++) {
snapShot = snapShot.where(searchCriteria[i].fieldName, searchCriteria[i].filterOp, searchCriteria[i].value);
}
let res = await snapShot.get();
return res.docs.map<T>(doc => ({ id: doc.id, ...doc.data() }) as T);
}
async get<T extends object>(collectionName: string): Promise<T[]> {
let res = await this.collection(collectionName).get();
return res.docs.map<T>(doc => ({ id: doc.id, ...doc.data() } as T));
}
async create<T extends object>(collectionName: string, item: T): Promise<T> {
return (await this.collection(collectionName).add(item)) as T;
}
async update<T extends object>(collectionName: string, id: string, item: T): Promise<firestore.WriteResult> {
var docRef = this.collection(collectionName).doc(id);
return await docRef.update(item);
}
async delete<T extends object>(collectionName: string, id: string): Promise<firestore.WriteResult> {
return await this.collection(collectionName).doc(id).delete();
}
}
I followed the example here: Firestore: Multiple conditional where clauses.
But i am getting the following error : dbcontext.ts:23:13 - error TS2740: Type 'Query<DocumentData>' is missing the following properties from type 'CollectionReference<DocumentData>': id, parent, path, listDocuments, and 2 more.
its failing in the mentioned below line
snapShot = snapShot.where(searchCriteria[i].fieldName, searchCriteria[i].filterOp, searchCriteria[i].value);
ISearchCriteria:
import { firestore } from "firebase-admin";
export interface ISearchCriteria {
fieldName: string | firestore.FieldPath,
filterOp: FirebaseFirestore.WhereFilterOp,
value: any
}
Upvotes: 3
Views: 2689
Reputation: 713
const getDocuments = (collection: string, queries: QueryWhereClause[]) => {
let collectionRef: firebase.firestore.Query<firebase.firestore.DocumentData> = firestore.collection(collection);
if (queries && queries.length) {
for (const query of queries) {
collectionRef = collectionRef.where(
query.field,
query.condition,
query.value
);
}
}
return collectionRef.get();
};
Adding (firebase.firestore.Query) as my collection type worked.
let collectionRef: firebase.firestore.Query<firebase.firestore.DocumentData> = firestore.collection(collection);
Upvotes: 1
Reputation: 317362
The problem is that your collection()
method returns a CollectionReference
, but where() returns a Query
. TypeScript is telling you that you can't assign a Query
object to a CollectionReference
variable.
If you look at the API documentation, you'll see that CollectionReference is actually a subclass of Query (it just returns all documents in the collection). When you call where()
, you're building a new Query that filters the documents from the prior Query.
Try making your collection()
return a Query instead so you can safely reassign snapShot
:
collection(collectionName: string): firestore.Query<firestore.DocumentData> {
return this.db.collection(collectionName);
}
BTW, your variable called snapShot
isn't a snapshot - it should probably be called query
.
Upvotes: 5