rxjs和firebase类型错误:无法添加属性0,对象不可扩展

izkcnapc  于 2023-02-13  发布在  其他
关注(0)|答案(1)|浏览(117)

我有一个Angular 的应用程序,连接到firebase的firestore作为后端数据库。
我正在尝试编写一个泛型函数来从firestore获取文档快照。
下面是我得到错误的函数:

/**
   * Get a 'listener' observable that subscribes to live document updates in the firestore db
   * @type the expected document type as interface
   * @param docPath path to document collection in firestore
   * @param docId id of document to get
   * @returns An Obseravble<DocumentSnapShot<Type>>
   */
  public watchDocument<T>(
    docPath: string,
    docId: string
  ): Observable<DocumentSnapshot<T>> {
    const docRef = doc(this.firestore, docPath, docId) as DocumentReference<T>;
    return fromEventPattern<DocumentSnapshot<T>>(
      (handler) => onSnapshot<T>(docRef, handler),
      (handler, unsubscribe) => unsubscribe()
    );
  }

我也尝试了这个版本的函数:

public watchDocument<T>(
    docPath: string,
    docId: string
  ): Observable<DocumentSnapshot<T>> {
    const docRef = doc(this.firestore, docPath, docId) as DocumentReference<T>;
    return new Observable<DocumentSnapshot<T>>((subscriber) =>
      onSnapshot<T>(docRef, subscriber.next, subscriber.error)
    );
  }

两个版本都在**onSnapshot(docRef,handler)**调用时抛出以下错误:

TypeError: Cannot add property 0, object is not extensible
    at Array.push (<anonymous>)
    at ObserverProxy.subscribe...

这个函数是从一个NGRX效果调用的。如果我只调用一个效果,这个函数就可以工作。但是如果这个函数是由以前的动作/效果调用的,那么它就会失败,并出现我上面引用的错误。

编辑:1

我认为发生的事情是NGRX冻结了一些东西。如果我只调用firestore函数,那么无论顺序如何,所有函数都可以工作。问题是,一旦我调用任何firebase身份验证函数,如signInWithEmailAndPassword,以下firestore函数将失败。

    • 问题:**

我需要帮助找出为什么这个错误时,与其他行动链。

tez616oj

tez616oj1#

由于onSnapshot返回unSubscribe方法,因此最好像您所做的那样向Observable返回unSubscription。
我已通过以下变更对此进行了测试:

watchDocument<T>(docPath: string,
    docId: string): Observable<DocumentSnapshot<T>> {
    const docRef = doc(this.firestore, docPath, docId) as DocumentReference<T>;
    return new Observable<DocumentSnapshot<T>>((subscriber) => {
      const subscription = onSnapshot<T>(docRef, snapshot => {
        subscriber.next(snapshot);
      });
      return () => {
        subscription();
      };
    });
  }

获取单据数据如下:

this.service.watchDocument(this.collectionName, this.documentId)
    .subscribe(document => {
      console.log(document.id, " ==> ", document.data())
    });

现在,将上述逻辑应用于fromEventPattern实现将变为:

watchDocumentWithEvent<T>(docPath: string,
    docId: string): Observable<DocumentSnapshot<T>> {
      const docRef = doc(this.firestore, docPath, docId) as DocumentReference<T>;
    return fromEventPattern<DocumentSnapshot<T>>(
      (handler) => {
        const subscription = onSnapshot<T>(docRef, handler);
        return () => subscription();
      },
      (subscription) => subscription()
    );
  }

由于fromEventPattern返回T或T[]形式返回的Observable,因此在这里,subscriptiononSnapshot调用返回的unsubscribe函数,它作为第二个参数传递给fromEventPattern,以允许fromEventPattern在取消订阅Observable时取消订阅。
引用自类型脚本与scode智能感知和firebase文档中的fromEventPattern和onSnapshot

相关问题