Error message stating: rxjs and firebase encountered a TypeError when attempting to add property 0 because the object is not

My angular application interacts with firebase firestore as the backend database.

I am working on a function to retrieve document snapshots from firestore in a generic way.

Here is the code snippet where I encounter an error:

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

I have also tried another version of the function:

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

Both versions result in the following error when calling onSnapshot(docRef, handler):

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

This function is invoked from an NGRX effect. It works fine when called individually but fails when chained with other actions/effects.

EDIT: 1

I suspect that something is being frozen by NGRX. The firestore functions work seamlessly when used alone, but they fail after any firebase authentication functions like signInWithEmailAndPassword are executed.


QUESTION:

I need assistance in understanding why these errors occur when this function is combined with other actions.

Answer №1

It is recommended to return the unsubscription method from the onSnapshot in order to properly handle it within the Observable, as demonstrated in your code.

I have conducted tests with the following modifications:

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

Retrieving document data using the above method:

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

By incorporating the same logic into your implementation of fromEventPattern, you can achieve:

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

The fromEventPattern function returns an Observable based on the type returned by the provided callback functions. In this case, the subscription serves as the unsubscribe method from onSnapshot, ensuring proper cancellation when unsubscribing from the Observable.

This information was gathered from sources such as RxJS documentation on fromEventPattern and references to onSnapshot from TypeScript VSCode IntelliSense and Firebase documentation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Setting the ariaLabel value in TypeScript is a straightforward process that involves defining the

In my TypeScript React application, I am attempting to dynamically set the ariaLabel value. However, ESLint is flagging an error: Property 'ariaLabel' does not exist on type 'HTMLButtonElement'. I have tried various types but none of t ...

Angular Material 2 Stepper Controls for Angular applications

I successfully implemented a linear stepper using the Angular Material 2 Stepper component. My project consists of forms in various components (component-a, component-b, component-c). I need the linear stepper in my main container component (container-com ...

Manage scss styles consistently across Angular projects with this Angular library designed to

In an effort to streamline my development process, I am looking to consolidate my commonly used styles that are defined in my Angular library. My goal is to easily leverage mixins, functions, variables, and more from my library in future projects. Previou ...

Error in Angular 7: Image is not being rendered

Currently, I am working on a project that involves Angular JS. I have been following this example: https://jsbin.com/gumaraz/edit?html,output However, I need to transition this code to Angular 7. I have tried upgrading the code from Angular.js to Angular ...

Begin the NextJS project by redirecting the user to the Auth0 page without delay

I am new to coding and currently working on a project using Typescript/NextJS with Auth0 integration. The current setup navigates users to a page with a login button that redirects them to the Auth0 authentication page. However, this extra step is unneces ...

What causes the HTML to not evaluate the values when the pipe is used?

I am currently utilizing a pipe for currency conversion, ensuring that the HTML values remain unevaluated. Let's take a look at the following pipe: transform(value: number, selectedCurrency: string, baseCurrency: string): number { if (selectedCu ...

The event listener for 'end' is not executing in a Node.js Firebase and Nylas Express application

I am currently working on setting up webhooks with Nylas. In their provided example, there is a middleware code that I am implementing in my TypeScript project using Firebase as the endpoint. When testing locally with ngrok, the middleware functions prop ...

The size of React's webpack bundle is quite hefty

A website I developed using React has a single page, but the production bundle size is 1.11 MiB. The app uses Firestore, Firebase Storage, Material-UI, and React-Redux, all of which work well except for the issue with the bundle size. https://i.stack.imgu ...

How can variables from state be imported into a TypeScript file?

Utilizing vue.js along with vuetify, I have a boolean value stored in state via Vuex defined in src/store/index.ts (named darkMode). This value is used within one of my view components inside a .vue file. However, I now wish to access the same variable in ...

Typescript is failing to perform type checking

I'm encountering an issue while trying to utilize TypeScript type checking with the following code snippet: abstract class Mammal { abstract breed(other: Mammal); } class Dog extends Mammal { breed(other: Dog) {} } class Cat extends Mammal { ...

Error in parsing: Unexpected token encountered. Expected a comma instead. Issue found in React with Typescript

I'm encountering a new error message that I haven't seen before... I've checked my code thoroughly and it seems to be correct, yet the error persists. Here is my code snippet: interface AuthState { token: string; user: User; } interfac ...

Error in Angular 2: Component unable to locate imported module

I'm facing an issue where a module I want to use in my application cannot be found. The error message I receive is: GET http://product-admin.dev/node_modules/angular2-toaster/ 404 (Not Found) The module was installed via NPM and its Github reposito ...

Request for /Account after Keycloak token request in Angular app

I have been working on an Angular and Keycloak project. I followed a tutorial that helped me integrate Keycloak into Angular, which can be found here: https://www.npmjs.com/package/keycloak-angular My public client is able to request a token, but when it ...

Raycasting in Three.js is ineffective on an object in motion

Working on a project that combines three.js and typescript, I encountered an issue while attempting to color a sphere by raycasting to it. The problem arises when the object moves - the raycast doesn't seem to acknowledge the new position of the objec ...

Tips for restricting additional input when maximum length is reached in an Angular app

In my Angular 6 application, I am working on implementing a directive that prevents users from typing additional characters in an input field. However, I want to allow certain non-data input keys such as tab, delete, and backspace. Currently, I have an if ...

Issue with Next.js hook: Uncaught TypeError - Unable to define properties of undefined (setting 'type')

Encountered an error while attempting to build my nextjs app. Strangely, this error wasn't present in the previous version of the app. I didn't make any changes to the config files, just added a few animation libraries and that's all, along ...

What is the best way to update the mat-tab when the routeParameters are modified?

I need to reinitialize the mat-tab-group in order to make the first tab active when there is a change in the routeParams. ts file: public index = 0; ngOnInit() { this.subscription = this.route.params.subscribe((routeParams: Params) => { // some ...

Unable to transfer data through Ionic popover

I've encountered an issue when trying to pass data to my popover component, as the data doesn't seem to be sent successfully. Code HTML <div class="message" id="conversation" *ngFor="let message of messages.notes"> <ion-row class= ...

Data loss occurs when the function malfunctions

Currently, I am working with Angular version 11. In my project, I am utilizing a function from a service to fetch data from an API and display it in a table that I created using the ng generate @angular/material:table command. Client Model export interfac ...

Angular2 import functions properly on the Windows operating system, however, it encounters issues on the Linux

import { Injectable } from '@angular/core'; import { Http, Response, Headers } from '@angular/http'; import { Observable } from 'rxjs/Observable'; import { User } from './../../class/User'; I am encountering the fol ...