invertase / stripe-firebase-extensions

Repository of Firebase Extensions built by Stripe.
https://firebase.google.com/products/extensions
Apache License 2.0
431 stars 162 forks source link

FirebaseError on createCheckoutSession #304

Open ElBouhaliMohamed opened 2 years ago

ElBouhaliMohamed commented 2 years ago

Bug report

Describe the bug

FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore
    at ba (index.esm2017.js?4515:14943)
    at FirestoreSessionDAO.eval (session.js?995f:116)
    at Generator.next (<anonymous>)
    at eval (session.js?995f:22)
    at new Promise (<anonymous>)
    at __awaiter (session.js?995f:18)
    at FirestoreSessionDAO.addSessionDoc (session.js?995f:115)
    at FirestoreSessionDAO.eval (session.js?995f:110)
    at Generator.next (<anonymous>)
    at eval (session.js?995f:22)

It seems that the firestore instance created in the FirestoreSessionDAO isn't correct or the collection() call is wrong.

To Reproduce

Init firebase and stripe

const app = !getApps().length ? initializeApp(firebaseConfig) : getApp()

const payments = getStripePayments(app, {
  productsCollection: 'products',
  customersCollection: 'customers'
})

export { app, payments }

import payments and use checkout function

import { payments } from '../services/firebase.service'
import { createCheckoutSession,  } from '@stripe/firestore-stripe-payments'

...

  methods: {
    checkout () {
      createCheckoutSession(payments, {
        price: 'price_1Jtax3GhjnzZribLiyQznali'
      }).then(session => {
        window.location.assign(session.url)
      }).catch(err => {
        console.log(err)
      })
    }
  }

...

When the method gets called there's the error in the console.

Expected behavior

Normal stripe checkout session.

System information

Windows, Chrome, firebase@9.0.2, @stripe/firestore-stripe-payments@0.0.3

Additional context

Add any other context about the problem here.

tommtt commented 2 years ago

Same problem: https://stackoverflow.com/questions/70013565/stripe-and-firebase-firebaseerror-expected-first-argument-to-collection-to-b?noredirect=1#comment123784766_70013565

RaynoldVanHeyningen commented 2 years ago

Same problem here, possibly related to Firebase ^9 ?

My firebase version: "firebase": "^9.1.3"

hiranya911 commented 2 years ago

This is likely a dependency management issue. The library is expecting a certain version of @firebase/firestore while a different one is installed with the app. Can somebody who can repro this issue please share their dependency tree with us (i.e. npm ls output)? Or even better, share a small, minimal repro that we can try locally.

tommtt commented 2 years ago

├── @emotion/react@11.4.1 ├── @emotion/styled@11.3.0 ├── @firebase/analytics 2@ extraneous ├── @firebase/app-check 2@ extraneous ├── @firebase/app-check-compat 2@ extraneous ├── @firebase/app-compat 2@ extraneous ├── @firebase/app@0.7.8 ├── @firebase/auth-compat 2@ extraneous ├── @firebase/database 2@ extraneous ├── @firebase/database-compat 2@ extraneous ├── @firebase/firestore 2@ extraneous ├── @firebase/firestore-compat 2@ extraneous ├── @firebase/functions 2@ extraneous ├── @firebase/functions-compat 2@ extraneous ├── @firebase/installations 2@ extraneous ├── @firebase/messaging 2@ extraneous ├── @firebase/messaging-compat 2@ extraneous ├── @firebase/performance 2@ extraneous ├── @firebase/performance-compat 2@ extraneous ├── @firebase/remote-config 2@ extraneous ├── @firebase/storage 2@ extraneous ├── @firebase/storage-compat 2@ extraneous ├── @material-ui/icons@4.11.2 ├── @mui/icons-material@5.0.0 ├── @mui/material@5.0.0 ├── @stripe/firestore-stripe-payments@0.0.3 ├── @testing-library/jest-dom@5.14.1 ├── @testing-library/react@11.2.7 ├── @testing-library/user-event@12.8.3 ├── faye-websocket 2@ extraneous ├── firebase 2@ extraneous ├── firebase@9.4.1 ├── react-dom@17.0.2 ├── react-quill@2.0.0-beta.4 ├── react-router-dom@5.3.0 ├── react-scripts@4.0.3 ├── react@17.0.2 └── web-vitals@1.1.2

RaynoldVanHeyningen commented 2 years ago

├── @chakra-ui/react@1.6.10 ├── @emotion/react@11.5.0 ├── @emotion/styled@11.3.0 ├── @fontsource/inter@4.5.0 ├── @stripe/firestore-stripe-payments@0.0.3 extraneous ├── @types/react@17.0.33 ├── date-fns@2.25.0 ├── eslint-config-next@11.1.0 ├── eslint@7.32.0 ├── firebase-admin@10.0.0 ├── firebase@9.1.3 ├── framer-motion@4.1.17 ├── js-cookie@3.0.1 ├── lodash@4.17.21 ├── next-transpile-modules@9.0.0 ├── next@12.0.2 ├── pino-logflare@0.3.12 ├── pino@7.1.0 ├── react-dom@17.0.2 ├── react-hook-form@7.18.0 ├── react-icons@4.3.1 ├── react@17.0.2 ├── swr@1.0.1 └── typescript@4.4.4

tommtt commented 2 years ago

Guys now it seems working! Awesome, thanks!

RaynoldVanHeyningen commented 2 years ago

Guys now it seems working! Awesome, thanks!

What did you change?

tommtt commented 2 years ago

Literally nothing. I just tried again to trigger the function and now it just works.

adam-bielasty commented 2 years ago

I downgraded from:

"@stripe/firestore-stripe-payments": "0.0.4", to "@stripe/firestore-stripe-payments": "0.0.3",

and the bug stopped occurring.

breadcrumbbuilds commented 2 years ago

Attempted downgrading, still have the same issue.

mmcenti commented 2 years ago

Still have this issue on 0.0.5 by the way

alxjpzmn commented 2 years ago

What made it work for me was ensuring that Firebase-related dependencies are the same for both my app and @stripe/firestore-stripe-payments via package.json overrides.

This is how the overrides in my package.json look like for 0.0.6 of the @stripe/firestore-stripe-payments and Firebase JS SDK 9.6.6:

"overrides": { "@firebase/app": "0.7.16", "@firebase/firestore": "3.4.4" }

It's not pretty but it works for now.

drtapha commented 2 years ago

i have same with "overrides": { "@firebase/app": "0.7.16", "@firebase/firestore": "3.4.4" }. i'm so confused. Someone have an idea ?

jonadeline commented 2 years ago

same issue here. using v.0.0.6 of stripe-payments. Tried the solutions mentioned above but that didn't work :(

Irian-Adappty commented 2 years ago

What made it work for me was ensuring that Firebase-related dependencies are the same for both my app and @stripe/firestore-stripe-payments via package.json overrides.

This is how the overrides in my package.json look like for 0.0.6 of the @stripe/firestore-stripe-payments and Firebase JS SDK 9.6.6:

"overrides": { "@firebase/app": "0.7.16", "@firebase/firestore": "3.4.4" }

It's not pretty but it works for now.

SEE EDIT BELOW

Previous message:

Thanks! I have used command npx howfat -r tree @stripe/firestore-stripe-payments (also I ran it with firebase package) to see exactly the version I needed, and with firebase@9.8.4 and @stripe/firestore-stripe-payments@0.0.6 installed I could make it work with the following override:

"overrides": {
    "@firebase/app": "0.7.29",
    "@firebase/firestore": "3.4.13"
  }

EDIT: It broke again with the same settings, for me it's an intermittent issue and it's hard to debug.

TheDomac commented 2 years ago

Any updates on this? For me using:

"overrides": {
    "@firebase/app": "0.7.29",
    "@firebase/firestore": "3.4.13"
  }

breaks the auth and is not working anyway. I'm getting FirebaseError: Firebase: Error (auth/network-request-failed). because of incompatibility (I don't have this issue when not using overrides)

Regarding Stripe payments, in my database, in /customers/:userId/checkout_sessions, I have error cannot read propery "stripeId" of null

Idk if this matters but I'm using yarn and resolutions instead of overrides

christophemarois commented 1 year ago

Was stuck on this for days. I have a monorepo setup with PNPM workspaces.

Temporarily fixed by forcing up-to-date dependencies by adding:

"pnpm": {
  "overrides": {
    "@stripe/firestore-stripe-payments@0.0.6>@firebase/app": "0.8.2",
    "@stripe/firestore-stripe-payments@0.0.6>@firebase/auth": "0.20.10",
    "@stripe/firestore-stripe-payments@0.0.6>@firebase/firestore": "3.7.1"
  }
}

to my root package.json. The particular versions where set to match the others I found commands like pnpm -F [app-name] why @firebase/app

Skwai commented 1 year ago

Experiencing this to. Very frustrating.

Update: so the fix is to force your package.json to use whatever version of these packages is listed in your firebase dependency (eg. by using resolutions if using yarn):

    "@firebase/app" "@firebase/auth" "@firebase/firestore"
GautierCo commented 1 year ago

Experiencing this to. Very frustrating.

Update: so the fix is to force your package.json to use whatever version of these packages is listed in your firebase dependency (eg. by using resolutions if using yarn):

    "@firebase/app" "@firebase/auth" "@firebase/firestore"

Thank you for your solution Same issue here... I hope this problem will be solved

For those who don't know how to make a "resolution", here's what I did in package.json:

{
   "resolutions": {
        "@firebase/app": "0.8.2",
        "@firebase/auth": "0.20.10",
        "@firebase/firestore": "3.7.1"
    },   
}

Don't forget to run yarn install

djkepa commented 1 year ago

Experiencing this to. Very frustrating. Update: so the fix is to force your package.json to use whatever version of these packages is listed in your firebase dependency (eg. by using resolutions if using yarn):

    "@firebase/app" "@firebase/auth" "@firebase/firestore"

Thank you for your solution Same issue here... I hope this problem will be solved

For those who don't know how to make a "resolution", here's what I did in package.json:

{
   "resolutions": {
        "@firebase/app": "0.8.2",
        "@firebase/auth": "0.20.10",
        "@firebase/firestore": "3.7.1"
    },   
}

Don't forget to run yarn install

Thanks bro!

after so much time looking for a solution!

RasicN commented 1 year ago

This break again with "firebase": "^10.1.0" ???

byroncoetsee commented 1 year ago

This is happening for me too using "^10.1.0" I've tried adding resolutions to the package.json file but no luck.

Any way to get around this or solve it @dackers86 ? Thank you

surafelbm commented 11 months ago

@byroncoetsee, were you able to resolve this, please? I am also on firebase: 10.0.0

surafelbm commented 11 months ago

This break again with "firebase": "^10.1.0" ???

@RasicN , any solutions? i am also on 10.0.0 and having the same issue

surafelbm commented 11 months ago

Was able to find a fix for ^10.0.0 Basically, the resolutions need to match whatever the current version you are using so for this version this worked:

"resolutions": {
    "@firebase/firestore": "4.1.3",
    "@firebase/auth": "1.3.0",
    "@firebase/app": "0.9.18"
  },

I just went to node_modules/firebase/package.json and copied the versions from there, I am sure there is a yarn command you can use to find that

Raketten1963 commented 11 months ago

I personally gave up on waiting and simply queried the tavbles myself, that works quite nicely but is a little extra work that we frankly expected Stripe to do...

fabhed commented 10 months ago

@surafelbm's solution worked for me with slightly different version on npm:

  "dependencies": {
    "@invertase/firestore-stripe-payments": "^0.0.7",
    "firebase": "10.1.0",
  },
  "overrides": {
    "@firebase/app": "0.9.15",
    "@firebase/auth": "1.1.0",
    "@firebase/firestore": "4.1.0"
  }

Note: If you use npm, use override instead of yarn's resolutions

dragoscv commented 8 months ago

Same problem still isn't fixed till this day. This temporary fix works as everyone above already said:

"overrides": { "@firebase/app": "0.9.25", "@firebase/auth": "1.5.1", "@firebase/firestore": "4.4.0" }

SpiZeak commented 7 months ago

I got the collection error before but using overrides to override the dependencies to the firebase package versions I get another error:

Uncaught (in promise) Error: Unexpected error while querying Firestore
    at FirestoreProductDAO.<anonymous> (@invertase_firestore-stripe-payments.js?v=c3306c19:665:15)
    at Generator.throw (<anonymous>)
    at rejected (@invertase_firestore-stripe-payments.js?v=c3306c19:493:32)

I am getting nowhere with this Firebase Extension...

dragoscv commented 7 months ago

I got the collection error before but using overrides to override the dependencies to the firebase package versions I get another error:

Uncaught (in promise) Error: Unexpected error while querying Firestore
    at FirestoreProductDAO.<anonymous> (@invertase_firestore-stripe-payments.js?v=c3306c19:665:15)
    at Generator.throw (<anonymous>)
    at rejected (@invertase_firestore-stripe-payments.js?v=c3306c19:493:32)

I am getting nowhere with this Firebase Extension...

Be sure you are having the rules of db set correctly. I've managed to not have any errors anymore, everything works fine for me. Maybe share more of your code to understand your problem

SpiZeak commented 7 months ago

I got the collection error before but using overrides to override the dependencies to the firebase package versions I get another error:

Uncaught (in promise) Error: Unexpected error while querying Firestore
    at FirestoreProductDAO.<anonymous> (@invertase_firestore-stripe-payments.js?v=c3306c19:665:15)
    at Generator.throw (<anonymous>)
    at rejected (@invertase_firestore-stripe-payments.js?v=c3306c19:493:32)

I am getting nowhere with this Firebase Extension...

Be sure you are having the rules of db set correctly. I've managed to not have any errors anymore, everything works fine for me. Maybe share more of your code to understand your problem

Sure! The error appears whether I use getProducts() or createCheckoutSession() in my React app.

I first initialize the firebase app with initializeApp().

payments is exported as follows:

import { getApp } from "firebase/app";
import { getStripePayments } from "@invertase/firestore-stripe-payments";

const app = getApp();
const payments = getStripePayments(app, {
    productsCollection: "Products",
    customersCollection: "Users",
});

export { payments };

I have the following in my React component:

import { payments } from '...'

useEffect(() => {
    (async () => {
        const products = await getProducts(payments, {
            includePrices: true,
        activeOnly: true,
        })
    })()
}, [])

My firestore rules are currently in "testing" mode with the following:

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
      match /{document=**} {
          allow read, write: if false;
      }

    ...

    match /Users/{uid} {
      allow read: if true;

      match /CheckoutSessions/{id} {
        allow read, write: if request.auth.uid == uid;
      }
      match /Subscriptions/{id} {
        allow read: if request.auth.uid == uid;
      }
      match /Payments/{id} {
        allow read: if request.auth.uid == uid;
      }
    }

    match /Products/{id} {
      allow read: if true;

      match /Prices/{id} {
        allow read: if true;
      }

      match /TaxRates/{id} {
        allow read: if true;
      }
    }

    ...
  }
}
dragoscv commented 7 months ago

Here is your problem (the getApp wasn't working for me either):

import { getApp } from "firebase/app";
import { getStripePayments } from "@invertase/firestore-stripe-payments";

const app = getApp();
const payments = getStripePayments(app, {
    productsCollection: "Products",
    customersCollection: "Users",
});

export { payments };

it should be something like this:

const firebaseApp: FirebaseApp = initializeApp(config);
const stripePayments = (firebaseApp: FirebaseApp): StripePayments => getStripePayments(firebaseApp, {
    productsCollection: "products",
    customersCollection: "/customers",
});
const getProductsF = async () => {
            const payments = stripePayments(firebaseApp)
            const products = await getProducts(payments, {
                includePrices: true,
                activeOnly: true,
            });
            // console.log(products);
            const productsArray: any[] = []
            products.forEach((product: any) => {
                if (product.metadata.app === 'haitips') {
                    productsArray.push(product);
                }
            })
            // console.log(productsArray)
            dispatch({ type: 'SET_PRODUCTS', payload: productsArray });
        }

        getProductsF();
SpiZeak commented 7 months ago

I tried doing it with your code just to end up with the same error message again..

Uncaught (in promise) Error: Unexpected error while querying Firestore
    at FirestoreProductDAO.<anonymous> (@invertase_firestore-stripe-payments.js?v=c3306c19:665:15)
    at Generator.throw (<anonymous>)
    at rejected (@invertase_firestore-stripe-payments.js?v=c3306c19:493:32)
dragoscv commented 7 months ago

I tried doing it with your code just to end up with the same error message again..

Uncaught (in promise) Error: Unexpected error while querying Firestore
    at FirestoreProductDAO.<anonymous> (@invertase_firestore-stripe-payments.js?v=c3306c19:665:15)
    at Generator.throw (<anonymous>)
    at rejected (@invertase_firestore-stripe-payments.js?v=c3306c19:493:32)

Check your firebase configuration variables. Be sure it works without using stripe-payments

SpiZeak commented 7 months ago

Nope no luck, everything works as soon as I uncomment the stripe extension function calls. I tried refactoring my code to remove complexity (as my dynamic firestore initialization) and use getFirestore() in the firebase.ts file without getApp() anywhere, but the problem still persists..

dragoscv commented 7 months ago

Nope no luck, everything works as soon as I uncomment the stripe extension function calls. I tried refactoring my code to remove complexity (as my dynamic firestore initialization) and use getFirestore() in the firebase.ts file without getApp() anywhere, but the problem still persists..

I understand your frustration. It took me two days to figure out what was the problem. I had to check how the stripe-payments module is constructed, but it wasn't from there. What I've sent you earlier (my code) actually works, as I'm working on the app right now. Keep trying until you figure it out

SpiZeak commented 7 months ago

Nope no luck, everything works as soon as I uncomment the stripe extension function calls. I tried refactoring my code to remove complexity (as my dynamic firestore initialization) and use getFirestore() in the firebase.ts file without getApp() anywhere, but the problem still persists..

I understand your frustration. It took me two days to figure out what was the problem. I had to check how the stripe-payments module is constructed, but it wasn't from there. What I've sent you earlier (my code) actually works, as I'm working on the app right now. Keep trying until you figure it out

Just wanted to say I solved this, it was the Firebase Rules that was the issue. Noticed this in Edge browser that gave extra information "firebase rules permission denied".

If you look closely you can see I've renamed CheckoutSessions, Subscriptions, Payments, Prices and TaxRates for some reason.. (looks better to me) but the extension wants them snake_cased.

dragoscv commented 7 months ago

Nope no luck, everything works as soon as I uncomment the stripe extension function calls. I tried refactoring my code to remove complexity (as my dynamic firestore initialization) and use getFirestore() in the firebase.ts file without getApp() anywhere, but the problem still persists..

I understand your frustration. It took me two days to figure out what was the problem. I had to check how the stripe-payments module is constructed, but it wasn't from there. What I've sent you earlier (my code) actually works, as I'm working on the app right now. Keep trying until you figure it out

Just wanted to say I solved this, it was the Firebase Rules that was the issue. Noticed this in Edge browser that gave extra information "firebase rules permission denied"

If you look closely you can see I've renamed CheckoutSessions, Subscriptions, Payments, Prices and TaxRates for some reason.. (looks better to me) but the extension wants them snake-cased.

I'm glad you did it. So it was what I first told you to check 😄

Bash4195 commented 5 months ago

Is there a solution to this that doesn't involve downgrading packages? Sorry but it's a little disheartening to find out a package is broken at step 2 of the documentation and find the issue has been there for more than 2 years.

SpiZeak commented 5 months ago

Same problem still isn't fixed till this day. This temporary fix works as everyone above already said:

"overrides": { "@firebase/app": "0.9.25", "@firebase/auth": "1.5.1", "@firebase/firestore": "4.4.0" }

@Bash4195 This will upgrade the firebase dependencies and making it work, I just checked and the latest versions seems to be: "overrides": { "@firebase/app": "0.9.29", "@firebase/auth": "1.6.2", "@firebase/firestore": "4.5.0" }

Bash4195 commented 5 months ago

I personally gave up on waiting and simply queried the tavbles myself, that works quite nicely but is a little extra work that we frankly expected Stripe to do...

@SpiZeak unfortunately that's not an acceptable solution for me. I'd prefer the solution above ^

erikslatter commented 3 months ago

I tried to upgrade to using createCheckoutSession() rather than creating a Firestore doc directly under customers/{id}/checkout_sessions and ran into this same issue. Pasting relevant npm ls below

├── @firebase/analytics@0.10.2 ├── @firebase/app@0.10.2 ├── @firebase/auth@1.7.2 ├── @firebase/firestore@4.6.1 ├── @firebase/functions@0.11.4 ├── @firebase/storage@0.12.4 ├── @floating-ui/react@0.26.0 ├── @invertase/firestore-stripe-payments@0.0.7

jorgealemangonzalez commented 1 month ago

-----WORKAROUND-----

I copy pasted all the required code and just used firestore library. Here you have the changed methods, the rest of non-exported methods were just copy pasted from the project source code.

Please take into account that:

All the methods from DuplicatedFromLibrary are just copy-pastes of the methods from this repository, version 0.0.7


import {CreateCheckoutSessionOptions, Session, StripePaymentsError} from '@invertase/firestore-stripe-payments'
import {
    checkAndUpdateCommonParams,
    checkLineItemParams,
    checkPriceIdParams,
    getTimeoutMillis,
    hasLineItems,
    waitForSessionId,
} from './DuplicatedFromLibrary.ts'
import {firestore} from '../firebase.ts'
import {addDoc, collection, CollectionReference, DocumentReference} from 'firebase/firestore'
import {stripePayments} from './payments.ts'
import {PriceIdSessionCreateParams} from '@invertase/firestore-stripe-payments/lib/session'

async function addSessionDoc(
    uid: string,
    params: PriceIdSessionCreateParams,
): Promise<DocumentReference> {
    console.log('UID:', uid)
    const sessions: CollectionReference = collection(
        firestore,
        stripePayments.customersCollection,
        uid,
        'checkout_sessions',
    )
    console.log('Sessions:', sessions)
    try {
        return await addDoc(sessions, params)
    } catch (err) {
        throw new StripePaymentsError(
            'internal',
            'Error while querying Firestore.',
            err,
        )
    }
}

async function createCheckoutSessionDb(
    uid: string,
    params: PriceIdSessionCreateParams,
    timeoutMillis: number,
): Promise<Session> {
    const doc: DocumentReference = await addSessionDoc(uid, params)
    return waitForSessionId(doc, timeoutMillis)
}

export async function createCheckoutSession(
    uid: string,
    params: PriceIdSessionCreateParams,
    options?: CreateCheckoutSessionOptions,
): Promise<Session> {
    params = {...params}
    checkAndUpdateCommonParams(params)
    if (hasLineItems(params)) {
        checkLineItemParams(params)
    } else {
        checkPriceIdParams(params)
    }

    const timeoutMillis: number = getTimeoutMillis(options?.timeoutMillis)
    return createCheckoutSessionDb(uid, params, timeoutMillis)
}
jorgealemangonzalez commented 1 month ago

I am literally copy pasting the functions just changing the imports and it works. I think the only problem here is that the web-sdk code is importing from "@firebase/..." instead of importing from "firebase/..." . I realized it because I was also using the @ in my project and I was getting the same errors.

All the firebase packages with the @ prefix are not meant to be used directly as stated in their npm doc:

This package is not intended for direct usage, and should only be used via the officially supported [firebase (https://www.npmjs.com/package/firebase) package.

@dackers86 Do you know who is in charge of the extension now?