Skip to content

Firestore database rules blocking stripe webhook updates #372

Closed as not planned
@camunity

Description

@camunity

Bug report

  • Extension name: [e.g. firestore-stripe-payments]

Describe the bug

I am using Stripe to allow users to pay for a subscription service in my React app. I am using the firebase stripe extension to write updates to my customers collection. I have setup stripe.js on the server side of my application following the best practices in the docs and everything seems to be working well with passing data between the client and the server, but my issue is that the Firebase collection for customers isn't updating with the subscription status.

Screen Shot 2022-04-10 at 8 57 15 AM

I'm using the stripe cli to monitor webhooks and confirmed that the customer.subscription.updated event is being called and passing back data confirming that the customer has successfully subscribed but the firestore collection isn't updating as per the handleWebhookEvents and manageSubscriptionStatusChange function inside of the extension source code.

The handleWebhookEvents function is throwing errors in the Firestore logs that says that customer cannot be found:
Firestore Stripe Extension handleWebhooks logs

My datastore rules are set to the default:
Firestore Security Rules

I believe the issue is that the rules for the customers collection require a user to only edit their own document, which makes complete sense but in the source code the handleWebhookEvents function uses this syntax to identify the user's document:

Screen Shot 2022-04-10 at 9 08 33 AM

Expected behavior

I would expect the customer to be returned and the collection to update with the subscription data from the webhook:
Screen Shot 2022-04-10 at 9 16 02 AM

System information

  • OS: macOS
  • Browser: Brave

Additional context

I thought that the issue may have been given how the function in the manageSubscriptionStatusChange is written it needs access to read every customer document for the where query to work.

 const customersSnap = await admin
        .firestore()
        .collection(config_1.default.customersCollectionPath)
        .where('stripeId', '==', customerId)
        .get();
    if (customersSnap.size !== 1) {
        throw new Error('User not found!');
    }

I changed my datastore rules to allow read access to every customer object and it is still failing. I wonder if the function were written more like

 const customersSnap = await admin
        .firestore()
        .collection(`config_1.default.customersCollectionPath/${stripeId}`)
        .get();
    if (customersSnap.size !== 1) {
        throw new Error('User not found!');
    }

Where the path directly looks for the customer/uid path if it would support the match clause in the security rules. I'm all outta ideas now that I've tried changing the security rules though.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions