Skip to content

getStripePayments -> ERROR FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore #614

@NylasDev

Description

@NylasDev

Issue with implementation of getStripePayments:

  • Extension name: @invertase/stripe-firebase-extensions
  • Project details:
    Angular 17 standalone app (no module.ts, the new app.config.ts) with Server Side Rendering enabled
    Firebase
    Stripe

The problem is:
Console Error
ERROR FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore

Description of issue:

I am trying to implement this extension. I am creating accounts using firebase and it's google authentication provider.

I have implemented my auth service that works through firebase.
I created a shop service that I wish to use to create a subscription.

Each time I try any sort of approach to connect to Firestore and get the collections I get the error above.

I also implemented the webhook from stripe and the restricted API. This seems to work partially. When I look in Firestore DB I only see the new products I create copied over.

When I create a new user it does not create a "customer" with the session UID, as I expect although I don't know if this is an issue or it's because I am not getting to that point to trigger those cloud functions.

This is my app.config.ts

import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import { getAuth, provideAuth } from '@angular/fire/auth';
import { getFirestore, provideFirestore } from '@angular/fire/firestore';
import { initializeApp, provideFirebaseApp } from '@angular/fire/app';

import { provideClientHydration } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';

const firebaseConfig = {
  apiKey: "x",
  authDomain: "x",
  projectId: "x",
  storageBucket: "x",
  messagingSenderId: "x",
  appId: "x",
  measurementId: "x"
};

export const appConfig: ApplicationConfig = {
  providers: [
    importProvidersFrom(
    provideFirebaseApp(() => initializeApp(firebaseConfig))),
                        importProvidersFrom(provideAuth(() => getAuth())),
                        importProvidersFrom(provideFirestore(() => getFirestore())),
    provideRouter(routes),
    provideClientHydration()
  ]
};


To Reproduce

This is my AuthenticationService

import {Auth, authState, getAuth, GoogleAuthProvider, signInWithPopup} from '@angular/fire/auth';
import { Injectable } from '@angular/core';
import {Router} from "@angular/router";

@Injectable({
  providedIn: 'root'
})
export class AuthenticationService {
  loggedIn: boolean = false;

  constructor(private auth: Auth, private router: Router)
  {

  }
  authState = getAuth();

  isLoggedIn(): Promise<boolean> {
    return new Promise((resolve, reject) => {
      this.authState.onAuthStateChanged((user) => {
        if (user) {
          resolve(true);
        } else {
          resolve(false);
        }
      });
    });
  }
  async loginWithGoogle() {
    const provider = new GoogleAuthProvider();
    try {
     // await setPersistence(this.auth, browserSessionPersistence);
      await signInWithPopup(this.auth, provider);
      console.log( 'Sign in successful');
      await this.router.navigate(['dashboard']);
    } catch (error: any) {
      console.error(error);
      if (error.code) {
        console.log(`${error.code}: ${error.message}`);
      } else {
        console.log('There was a problem signing in. Please try again.');
      }
    }
  }
  getGoogleUserData(): { displayName: string | null, photoURL: string | null } {
    const user = this.authState.currentUser;
    if (user !== null) {
      console.log("Sign-in provider: " + user.providerId);
      console.log("  Provider-specific UID: " + user.uid);
      console.log("  Name: " + user.displayName);
      console.log("  Email: " + user.email);
      console.log("  Photo URL: " + user.photoURL);
      const displayName = user.displayName || null;
      const photoURL = user.photoURL || null;
      return { displayName, photoURL };
    } else {
      return { displayName: null, photoURL: null };
    }
  }

  logout(): Promise<void> {
    // Sign out the user to remove the local session
    return this.auth.signOut().then(()=>{this.router.navigate(['/'])});
  }
}

This is my ShopService where the error occurs, it is the same for any request that involves getStripePayments

import { Injectable } from '@angular/core';
import {getApp} from "@angular/fire/app";
import {createCheckoutSession, getProducts, getStripePayments} from "@invertase/firestore-stripe-payments";
import {Auth} from "@angular/fire/auth";
import {Router} from "@angular/router";

@Injectable({
  providedIn: 'root'
})
export class ShopService {

  constructor(private auth: Auth, private router: Router) { }

  app = getApp();
  payments = getStripePayments(this.app, {
    productsCollection: "products",
    customersCollection: "customers",
  });
  async startSubscriptionCheckout(priceId: string, successUrl?: string, cancelUrl?: string) {
    debugger;
    const session = await createCheckoutSession(this.payments, {
      price: priceId,
      success_url: successUrl || window.location.origin,
      cancel_url: cancelUrl || window.location.origin,
    });
    window.location.assign(session.url);
  }

  async listProducts(includePrices: boolean = false, activeOnly: boolean = true, filters?: any[], limit?: number) {
    debugger;

    return await getProducts(this.payments, {
      includePrices,
      activeOnly,
      where: filters,
      limit
    });
  }
}

Expected behavior

Get a some form of result from firestore.

Actual result

Error in console, does not seem to be configuring the instance correctly.

Additional context

First time implementing in this standalone mode of angular, might be implementing something wrong.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions