首页 > 解决方案 > Firestore 和 Typescript 的动态 Where 条件

问题描述

我正在尝试使用Firestore Firebase 和TypeScript实现存储库模式。

代码:

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

我在这里遵循了示例:Firestore:多个条件 where 子句

但我收到以下错误: 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. 它在下面提到的行中失败

            snapShot = snapShot.where(searchCriteria[i].fieldName, searchCriteria[i].filterOp, searchCriteria[i].value);

搜索条件:

    import { firestore } from "firebase-admin";
    export interface ISearchCriteria {
        fieldName: string | firestore.FieldPath,
        filterOp: FirebaseFirestore.WhereFilterOp,
        value: any
    }

标签: typescriptfirebasegoogle-cloud-firestore

解决方案


问题是您的collection()方法返回 a CollectionReference,但 where() 返回 a Query。TypeScript 告诉您不能将Query对象分配给CollectionReference变量。

如果您查看 API 文档,您会发现CollectionReference实际上是 Query 的子类(它只是返回集合中的所有文档)。当您调用 时where(),您正在构建一个新的查询,该查询从先前的查询中过滤文档。

尝试将您的collection()退货改为查询,以便您可以安全地重新分配snapShot

collection(collectionName: string): firestore.Query<firestore.DocumentData> {
    return this.db.collection(collectionName);
}

顺便说一句,您调用的变量snapShot不是快照 - 它可能应该被调用query


推荐阅读