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 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');
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 && }
);
};
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);
}
});
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);
}
});
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.