Wie behebe ich den CORS-Fehler von Firebase Functions für PaymentMethodManager in meiner React-App?JavaScript

Javascript-Forum
Guest
 Wie behebe ich den CORS-Fehler von Firebase Functions für PaymentMethodManager in meiner React-App?

Post by Guest »

Ich habe eine React-Anwendung mit Stripe-Zahlungen. Ich möchte, dass Benutzer auf der Registerkarte „Zahlungen“ in den Einstellungen ihre Zahlungsmethoden anzeigen, hinzufügen, bearbeiten und entfernen können. Um dies zu erreichen, ruft mein Frontend eine Firebase Cloud-Funktion mit dem Namen „createSetupIntent“ auf. Wenn ich jedoch auf die Schaltfläche klicke, um eine Setup-Absicht zu erstellen, wird in der Browserkonsole der folgende CORS-Fehler angezeigt:

Zugriff zum Abrufen unter „https:/“ /us-central1-lurk-.cloudfunctions.net/createSetupIntent' vom Ursprung 'http://localhost:5173' wurde durch die CORS-Richtlinie blockiert:
Antwort auf Preflight-Anfrage nicht Zugangskontrolle passieren Überprüfen Sie:
Auf der angeforderten Ressource ist kein Header „Access-Control-Allow-Origin“ vorhanden.

Und die Anfrage schlägt fehl mit:< /p>

Code: Select all

POST https://us-central1-lurk-.cloudfunctions.net/createSetupIntent net::ERR_FAILED
Ich scheine immer noch irgendwo einen direkten Abruf durchzuführen, der einen CORS-Preflight auslöst. Wie konfiguriere oder behebe ich die Aufrufe, damit ich die Firebase Functions-onCall-Methode (httpsCallable) ordnungsgemäß verwenden kann, ohne auf diese CORS-Fehler zu stoßen?
Ich habe alle Abruf- oder benutzerdefinierten PostJSON-Aufrufe durch httpsCallable von ersetzt das Firebase SDK in PaymentMethodManager.jsx.
Ich habe meinen Firebase Functions-Code (in createSetupIntent) überprüft, um sicherzustellen, dass er exportiert wird als Functions.https.onCall, daher sollte es das typische CORS umgehen, wenn ich httpsCallable verwende.
Ich habe in einigen Funktionsdateien cors(...)-Middleware hinzugefügt, um „origin: true“ zu ermöglichen, aber ich Mir wurde klar, dass onCall-Funktionen dies möglicherweise nicht benötigen, wenn ich nur httpsCallable verwende.
Ich habe darauf geachtet, meine Funktionen erneut bereitzustellen.
Ich habe überprüft, dass meine Importe korrekt sind :

Code: Select all

import { httpsCallable } from 'firebase/functions';
const createSetupIntentFn = httpsCallable(functions, 'createSetupIntent');
Der Fehler deutet jedoch darauf hin, dass die Funktion immer noch über einen direkten POST an cloudfunctions.net aufgerufen wird, anstatt die normale httpsCallable-Pipeline zu durchlaufen.
I Ich möchte sicherstellen, dass alle Verweise auf createSetupIntent über httpsCallable erfolgen und keine direkten Abrufaufrufe verbleiben.
PaymentMethodManager.jsx

Code: Select all

import React, { useState } from 'react';
import { functions } from '../firebase';
import { httpsCallable } from 'firebase/functions';
import { useToast } from '@chakra-ui/react';

export const PaymentMethodManager = () => {
const [showAddCard, setShowAddCard] = useState(false);
const toast = useToast();

const handleAddPaymentMethod = async () => {
try {
// Attempt to create a setup intent via httpsCallable
const createSetupIntentFn = httpsCallable(functions, 'createSetupIntent');
const { data } = await createSetupIntentFn();

if (!data || !data.clientSecret) {
throw new Error('Missing client secret from createSetupIntent response');
}
// Use data.clientSecret with Stripe.js to confirm a card setup
console.log('Setup Intent created:', data.clientSecret);
} catch (error) {
console.error('Error creating setup intent:', error);
toast({
title: 'Error',
description: error.message,
status: 'error',
duration: 3000,
});
}
};

return (


Add Payment Method

{showAddCard && }

);
};
createSetupIntent (aus meinem Stripe.js)

Code: Select all

exports.createSetupIntent = functions.https.onCall(async (data, context) =>  {
if (!context.auth) {
throw new functions.https.HttpsError('unauthenticated', 'Must be logged in');
}

try {
console.log('Creating setup intent for user:', context.auth.uid);

// Get user's Stripe customer ID from Firestore
const userDoc = await admin.firestore().collection('userInfo').doc(context.auth.uid).get();
const userData = userDoc.exists ? userDoc.data() : {};
let customerId = userData.stripeCustomerId;

// If no customer ID exists, create a new customer
if (!customerId) {
console.log('No customer ID found, creating new customer');
const customer = await stripe.customers.create({
email: context.auth.token.email,
metadata: {
firebaseUID: context.auth.uid
}
});
customerId = customer.id;
console.log('Created new customer:', customerId);

// Save the customer ID to Firestore
await admin.firestore().collection('userInfo').doc(context.auth.uid).set({
stripeCustomerId: customerId,
email: context.auth.token.email,
updatedAt: admin.firestore.FieldValue.serverTimestamp()
}, { merge: true });
} else {
console.log('Found existing customer:', customerId);
}

// Create a setup intent for the customer
const setupIntent = await stripe.setupIntents.create({
customer: customerId,
payment_method_types: ['card'],
usage: 'off_session',
metadata: {
firebaseUID: context.auth.uid,
customerId: customerId
}
});

console.log('Created setup intent:', setupIntent.id);

return {
clientSecret: setupIntent.client_secret,
customerId: customerId
};
} catch (error) {
console.error('Error in createSetupIntent:', error);
throw new functions.https.HttpsError('internal', error.message);
}
});
getPaymentMethods (von meinem Stripe.js)

Code: Select all

exports.getPaymentMethods = functions.https.onCall(async (data, context) => {
// Add CORS headers if needed
const corsMiddleware = (req, res) => new Promise((resolve, reject) => {
cors(req, res, (err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
});

try {
if (context.rawRequest &&  context.rawResponse) {
await corsMiddleware(context.rawRequest, context.rawResponse);
}

if (!context.auth) {
throw new functions.https.HttpsError('unauthenticated', 'Must be logged in');
}

console.log('Getting payment methods for user:', context.auth.uid);

const userDoc = await admin.firestore().collection('userInfo').doc(context.auth.uid).get();

if (!userDoc.exists) {
console.log('User document not found, creating new document');
await admin.firestore().collection('userInfo').doc(context.auth.uid).set({
email: context.auth.token.email,
createdAt: admin.firestore.FieldValue.serverTimestamp()
});
}

const userData = userDoc.exists ? userDoc.data() : {};
let customerId = userData.stripeCustomerId;

if (!customerId) {
console.log('No customer ID found, creating new customer');
const customer = await stripe.customers.create({
email: context.auth.token.email,
metadata: {
firebaseUID: context.auth.uid
}
});
customerId = customer.id;
console.log('Created new customer:', customerId);

// Save the customer ID to Firestore
await admin.firestore().collection('userInfo').doc(context.auth.uid).update({
stripeCustomerId: customerId
});
} else {
console.log('Found existing customer:', customerId);
}

// Get payment methods
const paymentMethods = await stripe.paymentMethods.list({
customer: customerId,
type: 'card'
});

console.log('Found payment methods:', paymentMethods.data.length);

return {
paymentMethods: paymentMethods.data,
customerId: customerId
};
} catch (error) {
console.error('Error in getPaymentMethods:', error);
throw new functions.https.HttpsError('internal', error.message);
}
});
Trotz der Verwendung von httpsCallable zeigt die Registerkarte „Netzwerk“ meiner Entwicklertools jedoch einen POST an …cloudfunctions.net/createSetupIntent mit einer Preflight-OPTIONS-Anfrage an, die mit der Fehlermeldung „Keine Zugriffskontrolle-Zulassen-“ fehlschlägt. „Origin'-Header“-Meldung. Ich vermute, dass irgendwo in meinem Code immer noch ein direkter Abrufaufruf übrig ist oder eine Fehlkonfiguration im Firebase Functions-Setup vorliegt.
Ich suche nach Anleitung, wie ich den verbleibenden Direktaufruf lokalisieren oder meine onCall-Funktion richtig konfigurieren kann /cors, damit die Anfrage nicht mehr fehlschlägt. Mein Ziel ist es, einen voll funktionsfähigen PaymentMethodManager zu haben, der aktuelle Zahlungsmethoden auflistet und das Hinzufügen neuer Zahlungsmethoden ohne CORS-Probleme ermöglicht.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post