Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
NylasDev opened this issue Mar 5, 2024 · 11 comments

Comments

@NylasDev
Copy link

NylasDev commented Mar 5, 2024

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.

@NylasDev
Copy link
Author

NylasDev commented Mar 5, 2024

A console.log of the app instance in shop.service.ts

Firebase app instance: FirebaseAppImpl {
  _isDeleted: false,
  _options: {
    apiKey: 'x',
    authDomain: 'x',
    projectId: 'x',
    storageBucket: 'x',
    messagingSenderId: 'x',
    appId: 'x',
    measurementId: 'x'
  },
  _config: { name: '[DEFAULT]', automaticDataCollectionEnabled: false },
  _name: '[DEFAULT]',
  _automaticDataCollectionEnabled: false,
  _container: ComponentContainer {
    name: '[DEFAULT]',
    providers: Map(20) {
      'platform-logger' => [Provider],
      'heartbeat' => [Provider],
      'fire-core-version' => [Provider],
      'fire-core-esm2017-version' => [Provider],
      'fire-js-version' => [Provider],
      'fire-js-all-app-version' => [Provider],
      'auth' => [Provider],
      'auth-internal' => [Provider],
      'fire-auth-node-version' => [Provider],
      'fire-auth-esm2017-version' => [Provider],
      'firestore' => [Provider],
      'fire-fst-node-version' => [Provider],
      'fire-fst-esm2017-version' => [Provider],
      'angularfire-core-version' => [Provider],
      'angularfire-app-version' => [Provider],
      'angular-server-version' => [Provider],
      'angularfire-auth-version' => [Provider],
      'angularfire-fst-version' => [Provider],
      'app' => [Provider],
      'app-check-internal' => [Provider]
    }
  }
}

@NylasDev
Copy link
Author

NylasDev commented Mar 5, 2024

package.json

{
  "name": "dungeon-maker-ai-frontend",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "serve:ssr:dungeon-maker-ai-frontend": "node dist/dungeon-maker-ai-frontend/server/server.mjs"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^17.2.0",
    "@angular/common": "^17.2.0",
    "@angular/compiler": "^17.2.0",
    "@angular/core": "^17.2.0",
    "@angular/fire": "^17.0.1",
    "@angular/forms": "^17.2.0",
    "@angular/platform-browser": "^17.2.0",
    "@angular/platform-browser-dynamic": "^17.2.0",
    "@angular/platform-server": "^17.2.0",
    "@angular/router": "^17.2.0",
    "@angular/ssr": "^17.2.1",
    "@invertase/firestore-stripe-payments": "^0.0.7",
    "@ng-bootstrap/ng-bootstrap": "^16.0.0",
    "@popperjs/core": "^2.11.8",
    "bootstrap": "^5.3.2",
    "bootstrap-icons": "^1.11.3",
    "express": "^4.18.2",
    "ngx-bootstrap": "^12.0.0",
    "rxjs": "~7.8.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.14.3"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^17.2.1",
    "@angular/cli": "^17.2.1",
    "@angular/compiler-cli": "^17.2.0",
    "@angular/localize": "^17.2.0",
    "@types/express": "^4.17.17",
    "@types/jasmine": "~5.1.0",
    "@types/node": "^18.18.0",
    "jasmine-core": "~5.1.0",
    "karma": "~6.4.0",
    "karma-chrome-launcher": "~3.2.0",
    "karma-coverage": "~2.2.0",
    "karma-jasmine": "~5.1.0",
    "karma-jasmine-html-reporter": "~2.1.0",
    "typescript": "~5.3.2"
  }
}

@joelshotton
Copy link

I'm having this same issue trying to use this SDK in a react app!

@connorbrc
Copy link

did you ever figure this out? running into same problem.

@NylasDev
Copy link
Author

NylasDev commented Apr 9, 2024 via email

@tolypash
Copy link

tolypash commented Jun 7, 2024

I have the same issue! Perhaps it's a Node JS thing?

@DougieBoi227
Copy link

Same issue using angular-fire. Anyone figure this out yet?

@nomadts
Copy link

nomadts commented Sep 26, 2024

I am having the same issue. How did you overcome this issue? Is there an alternative to that?

@DougieBoi227
Copy link

I am having the same issue. How did you overcome this issue? Is there an alternative to that?
The problem is when using angular fire, the wires get crossed.

Not a great solution but I ended going into the node modules and fixing it myself.
For example in node_modules/@invertase/firestore-stripe-payments/lib/payment.js
I changed all the getFirestores (and everything with it) to be imported from "@angular/fire/firestore". I had to go through all the main js files in there and do that.

All is working now but not sure I want something this flaky especially when dealing with payments. May be better to ditch the whole extension and implement stripe from scratch unfortunately.

@DanielGiljam
Copy link

I dunno if this has been said, but it works well with @angular/fire@7 but breaks in @angular/fire@16 and onwards. Not sure if this library is to blame or if it's @angular/fire's fault.

@agoransson
Copy link

This PR helped me. #645

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants