1

I have an Angular frontend app that is configured to run across 3 backend environments. DEV running off the local Firebase emulator (demo_myAppName) TEST (myAppName-test) & PROD (myAppName) which are both separate "real" Firebase projects.

The app is using Firebase Auth, Firestore, Functions, which all work across the 3 environments. So far I have been able to get the Stripe Payments extension installed, configured and working in the TEST & PROD environments.

I am however struggling to get this Extension working in my DEV environment (on Firebase Emulator).

I have attempted to understand and follow the instructions in the Firebase docs Manage project configurations with the Extensions manifest.

I have exported the extensions configuration for my TEST project (as DEV should have the same config, API keys etc.) using

firebase ext:install --local stripe/firestore-stripe-payments

Then when through the install steps, providing my stripe restricted key and a private webhook key


i  extensions: ensuring required API firebaseextensions.googleapis.com is enabled...
+  extensions: required API firebaseextensions.googleapis.com is enabled
i  extensions: Checking project IAM policy...
+  extensions: Project IAM policy OK
!  extensions: As of firebase-tools@11.0.0, the `--local` flag is no longer required, as it is the default behavior.
i  extensions: information about 'stripe/firestore-stripe-payments@0.3.3':
Name: Run Payments with Stripe
Publisher: stripe
Description: Controls access to paid content by syncing your one-time and recurring payments with Firebase Authentication.
License: Apache-2.0
Source code: https://github.com/stripe/stripe-firebase-extensions/tree/master/firestore-stripe-payments
Roles granted to this Extension:
  Secret Manager Secret Accessor (Allows accessing 
the payload of secrets.)
  Firebase Authentication Admin (Full read/write access to Firebase Authentication resources.)        
  Cloud Datastore User (Provides read/write access 
to data in a Cloud Datastore database. Intended for application developers and service accounts.)     

? Do you wish to continue? Yes
? Please enter a new name for this instance: 
demo-cogenii
i  extensions: answer the questions below to configure your extension:

Cloud Functions deployment location: Where do you want to deploy the functions created for this extension? You usually want a location close to your database. For help selecting a location, refer to the location selection guide (https://firebase.google.com/docs/functions/locations).
? Which option do you want enabled for this        
parameter? Select an option with the arrow keys,   
and use Enter to confirm your choice. You may only 
select one option. Iowa (us-central1)

Products and pricing plans collection: What is the 
path to the Cloud Firestore collection where the extension should store Stripe pricing plans?
? Enter a value for Products and pricing plans     
collection: products

Customer details and subscriptions collection: What is the path to the Cloud Firestore collection where the extension should store Stripe customer details? This can be the location of an existing user collection, the extension will not overwrite your existing data but rather merge the Stripe data into your existing uid docs.
? Enter a value for Customer details and 
subscriptions collection: users

Stripe configuration collection (Optional): What is the path to the Cloud Firestore collection where the extension should store Stripe configuration?    
? Enter a value for Stripe configuration 
collection: configuration

Sync new users to Stripe customers and Cloud Firestore: Do you want to automatically sync new users to customer objects in Stripe? If set to 'Sync', the 
extension will create a new customer object in Stripe and add a new doc to the customer collection in 
Firestore when a new user signs up via Firebase Authentication. If set to 'Do not sync' (default), the extension will create the customer object "on the 
fly" with the first checkout session creation.     
? Which option do you want enabled for this        
parameter? Select an option with the arrow keys,   
and use Enter to confirm your choice. You may only 
select one option. Do not sync

Automatically delete Stripe customer objects: Do you want to automatically delete customer objects in 
Stripe? When a user is deleted in Firebase Authentication or in Cloud Firestore and set to 'Auto delete' the extension will delete their customer object 
in Stripe which will immediately cancel all subscriptions for the user.
? Which option do you want enabled for this        
parameter? Select an option with the arrow keys,   
and use Enter to confirm your choice. You may only 
select one option. Do not delete

Stripe API key with restricted access: What is your Stripe API key? We recommend creating a new restricted key (https://stripe.com/docs/keys#limit-access) with write access only for the "Customers", "Checkout Sessions" and "Customer portal" resources. And read-only access for the "Subscriptions" and "Prices" resources.
? Where would you like to store your secrets? You
must select at least one value Local file (Used by
emulator only)
i  extensions: Configure a local secret value for Extensions Emulator
? This secret will be stored in
./extensions/demo-myAppName.secret.local.
Enter value for "Stripe API key with restricted
access" to be used by Extensions Emulator:
i  extensions: Configure a local secret value for Extensions Emulator
? This secret will be stored in ./extensions/demo-cogenii.secret.local.
Enter value for "Stripe API key with restricted access" to be used by Extensions Emulator:
<KEY removed>

Stripe webhook secret (Optional): This is your signing secret for a Stripe-registered webhook. This webhook can only be registered after installation. Leave this value untouched during installation, then follow the postinstall instructions for registering your webhook and configuring this value.
? Where would you like to store your secrets? If you don't want to set this optional secret, leave both options unselected to 
skip it Local file (Used by emulator only)
i  extensions: Configure a local secret value for Extensions Emulator
? This secret will be stored in ./extensions/demo-cogenii.secret.local.
Enter value for "Stripe webhook secret" to be used by Extensions Emulator: < <KEY removed>

Minimum instances for createCheckoutSession function: Set the minimum number of function instances that should be always be available to create Checkout Sessions. This number can be adjusted to reduce cold starts and increase the responsiveness of Checkout Session creation requests. Suggested values are 0 or 1. Please note this setting will likely incur billing costss, see the Firebase documentation (https://firebase.google.com/docs/functions/manage-functions#reduce_the_number_of_cold_starts) for more informati


Enable Events: If you enable events, you can write custom event handlers (https://firebase.google.com/docs/extensions/install-extensions#eventarc) that respond to these events.                                                 ttps://firebase.google.com/docs/extensions/install-ext

You can always enable or disable events later. Events will be emitted via Eventarc. Fees apply (https://cloud.google.com/eventarc/pricing).           ventarc. Fees apply (https://cloud.google.com/eventarc


? Would you like to enable events? No
+  Wrote extensions to firebase.json...
+  Wrote extensions/demo-myAppName.env
+  Wrote extensions/demo-myAppName.secret.local
i  extensions: The behavior of ext:install, ext:update, ext:configure, and 
ext:uninstall has changed in firebase-tools@11.0.0. Instead of deploying exext:uninstall has changed in firebase-tools@11.0.0. Intensions directly, changes to extension instances will be written to fireba be written to firebase.json and ./extensions/*.env. Tse.json and ./extensions/*.env. Then firebase deploy (--only extensions) wiebase project. See https://firebase.google.com/docs/exll deploy the changes to your Firebase project. See https://firebase.google.com/docs/extensions/manifest for more details.

This created the extensions folder with the demo-myAppName.env & demo-myAppName.secret.env config file as expected, as follows:

When I start the emulators I see the following


i  emulators: Starting emulators: auth, functions, firestore, hosting, extensions
i  emulators: Detected demo project ID "demo-myAppName", emulated services will use a demo configuration and attempts to access non-emulated services for this project will fail.
!  Function 'createPortalLink is missing a trigger in extension.yaml. Please add one, as triggers defined in code are ignored.
!  Function 'handleWebhookEvents is missing a trigger in extension.yaml. Please add one, as 
triggers defined in code are ignored.
!  Function 'createPortalLink is missing a trigger in extension.yaml. Please add one, as triggers defined in code are ignored.
!  Function 'handleWebhookEvents is missing a trigger in extension.yaml. Please add one, as 
triggers defined in code are ignored.
i  firestore: Importing data from .\myAppName\firebase-demo-data\firestore_export\firestore_export.overall_export_metadata
i  firestore: Firestore Emulator logging to firestore-debug.log
+  firestore: Firestore Emulator UI websocket is running on 9150.
i  auth: Importing config from .\myAppName\firebase-demo-data\auth_export\config.json
i  auth: Importing accounts from .\myAppName\firebase-demo-data\auth_export\accounts.json
i  hosting[demo-myAppName]: Serving hosting files from: www
+  hosting[demo-myAppName]: Local server: http://127.0.0.1:5000
i  ui: Emulator UI logging to ui-debug.log
i  functions: Watching "C:\Users\User\.cache\firebase\extensions\stripe\firestore-stripe-payments@0.3.3\functions" for Cloud Functions...
+  functions: Loaded functions definitions from source: createCustomer, createCheckoutSession, createPortalLink, handleWebhookEvents, onUserDeleted, onCustomerDataDeleted.
+  functions[us-central1-ext-demo-myAppName-createCustomer]: auth function initialized.       
+  functions[us-central1-ext-demo-myAppName-createCheckoutSession]: firestore function initialized.
+  functions[us-central1-ext-demo-myAppName-createPortalLink]: http function initialized (http://127.0.0.1:5001/demo-myAppName/us-central1/ext-demo-myAppName-createPortalLink).
+  functions[us-central1-ext-demo-myAppName-handleWebhookEvents]: http function initialized (http://127.0.0.1:5001/demo-myAppName/us-central1/ext-demo-myAppName-handleWebhookEvents).        
+  functions[us-central1-ext-demo-myAppName-onUserDeleted]: auth function initialized.        
+  functions[us-central1-ext-demo-myAppName-onCustomerDataDeleted]: firestore function initialized.
i  functions: Watching ".\myAppName\functions" for Cloud Functions...
+  functions: Using node@16 from host.
+  functions: Loaded functions definitions from source: listAuthUsersHTTP, listAuthUsers, userUpdated, userCreated, userDeleted.
+  functions[us-central1-listAuthUsersHTTP]: http function initialized (http://127.0.0.1:5001/demo-myAppName/us-central1/listAuthUsersHTTP).
+  functions[us-central1-listAuthUsers]: http function initialized (http://127.0.0.1:5001/demo-myAppName/us-central1/listAuthUsers).
+  functions[us-central1-userUpdated]: firestore function initialized.
+  functions[us-central1-userCreated]: firestore function initialized.
+  functions[us-central1-userDeleted]: auth function initialized.

┌─────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! It is now safe to connect your app. │
│ i  View Emulator UI at http://127.0.0.1:4000/               │
└─────────────────────────────────────────────────────────────┘

┌────────────────┬────────────────┬──────────────────────────────────┐
│ Emulator       │ Host:Port      │ View in Emulator UI              │
├────────────────┼────────────────┼──────────────────────────────────┤
│ Authentication │ 127.0.0.1:9099 │ http://127.0.0.1:4000/auth       │
├────────────────┼────────────────┼──────────────────────────────────┤
│ Functions      │ 127.0.0.1:5001 │ http://127.0.0.1:4000/functions  │
├────────────────┼────────────────┼──────────────────────────────────┤
│ Firestore      │ 127.0.0.1:8080 │ http://127.0.0.1:4000/firestore  │
├────────────────┼────────────────┼──────────────────────────────────┤
│ Hosting        │ 127.0.0.1:5000 │ n/a                              │
├────────────────┼────────────────┼──────────────────────────────────┤
│ Extensions     │ 127.0.0.1:5001 │ http://127.0.0.1:4000/extensions │
└────────────────┴────────────────┴──────────────────────────────────┘
  Emulator Hub running at 127.0.0.1:4400
  Other reserved ports: 4500, 9150
┌───────────────────────────┬────────────────────────────────────────┬────────────────────────────────────────────────────────────┐
│ Extension Instance Name   │ Extension Ref                          │ View in Emulator UI  
                                      │
├───────────────────────────┼────────────────────────────────────────┼────────────────────────────────────────────────────────────┤
│ demo-myAppName              │ stripe/firestore-stripe-payments@0.3.3 │ http://127.0.0.1:4000/extensions/demo-myAppName          │
└───────────────────────────┴────────────────────────────────────────┴────────────────────────────────────────────────────────────┘
Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.

When I go to the Emulator UI and click on Extensions I see the extension and I can see the config.

When I go in to Stripe Test Dasboard and add or update a Product (for example) I can see the change reflected in my TEST Firestore but nothing is coming through to my DEV (emulator) Firestore.

When I check the logs for the Stripe webhook there is 404 error

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>404 Page not found</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Page not found</h1>
<h2>The requested URL was not found on this server.</h2>
<h2></h2>
</body></html>

I know I'm missing something but following the doc I am not sure what it is.

IM72
  • 11
  • 2

0 Answers0