I have installed the "Run Subscription Payments with Stripe" extension in Firebase.
When I try the to subscribe a user to a plan I get an error saying "snap.data is not a function". I use the following code:
db
.collection('customers')
.doc(cred.user.uid)
.collection('checkout_sessions')
.add({
price: 'price_1GqIC8HYgolSBA35zoTTN2Zl',
success_url: window.location.origin,
cancel_url: window.location.origin,
}).then(() => {
// Wait for the CheckoutSession to get attached by the extension
db
.collection('customers')
.doc(cred.user.uid)
.collection('checkout_sessions').onSnapshot((snap) => {
console.log(snap)
const { sessionId } = snap.data();
if ({sessionId}) {
console.log(sessionId)
// We have a session, let's redirect to Checkout
// Init Stripe
const stripe = Stripe('pk_test_ZEgiqIsOgob2wWIceTh0kCV4001CPznHi4');
stripe.redirectToCheckout({ sessionId });
};
});
});
This is a .then variation on the code example provided by the Firebase team:
const docRef = await db
.collection('customers')
.doc(currentUser.uid)
.collection('checkout_sessions')
.add({
price: 'price_1GqIC8HYgolSBA35zoTTN2Zl',
success_url: window.location.origin,
cancel_url: window.location.origin,
});
// Wait for the CheckoutSession to get attached by the extension
docRef.onSnapshot((snap) => {
const { sessionId } = snap.data();
if (sessionId) {
// We have a session, let's redirect to Checkout
// Init Stripe
const stripe = Stripe('pk_test_1234');
stripe.redirectToCheckout({ sessionId });
}
});
I got an error with the await function, saying "Uncaught SyntaxError: await is only valid in async function". So I refactered the code to a .then variant.
When I run this code from a button.addEventListener("click) I get an error saying snap.data is not a function.
I checked snap and it is populated
The customer gets created in Firestore and in Stripe dashboard, the customer session gets created.
What goes wrong here? There is a similair question on Stackoveflow ( Run Subscription Payments with Stripe Firebase Extension Webhook Not Firing ), but there is no answer, so I'm trying again.
Your query:
db
.collection('customers')
.doc(cred.user.uid)
.collection('checkout_sessions')
can fetch possibly multiple documents at once. The object it yields is a QuerySnapshot type object that can contain zero or more documents in the results et. That's what your snap
is here - a QuerySnapshot . You'll notice that it doesn't have a data()
method. That's for DocumentSnapshot objects, where you know you either have a single document or not.
If you have a QuerySnapshot, you'll have to iterate it to get all possible document snapshots out of it, as illustrated in the documentation .
But it seems that's not even what you want to do. It looks like you want to access the document that was previously added using add()
. If that's what you want, you shouldn't be querying the entire collection as you are now. Just locate the single document you want and add a listener to it .
You need to listen to updates to the specific document that you juts added via the .add()
function. This function returns a reference to that specific document: https://github.com/stripe/stripe-firebase-extensions/blob/next/firestore-stripe-subscriptions/POSTINSTALL.md#start-a-subscription-with-stripe-checkout
If you don't want to / can't use async/await syntax you will need to get that document reference from the .then()
function: https://firebase.google.com/docs/firestore/manage-data/add-data#web_6
db.collection("customers")
.doc(user)
.collection("checkout_sessions")
.add({
price: "price_1I42zfKct2IqsPff6b6vFNKx",
success_url: window.location.origin,
cancel_url: window.location.origin,
})
.then((docRef) => {
docRef.onSnapshot((snap) => {
const { sessionId } = snap.data();
if ({ sessionId }) {
console.log(sessionId);
// We have a session, let's redirect to Checkout
// Init Stripe
const stripe = Stripe("pk_test_ZEgiqIsOgob2wWIceTh0kCV4001CPznHi4");
stripe.redirectToCheckout({ sessionId });
}
});
});
I don't know if this has been resolved. I had a similar issue and changed tsconfig.jason
"compilerOptions": {
...
"strict": false,
...
}
That did it for me.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.