Firebase 扩展:使用 Stripe 运行订阅付款不会返回 sessionId
Posted
技术标签:
【中文标题】Firebase 扩展:使用 Stripe 运行订阅付款不会返回 sessionId【英文标题】:Firebase extension: Run Subscription Payments with Stripe doesn't return a sessionId 【发布时间】:2020-12-19 23:28:50 【问题描述】:我已在 Firebase 中安装了“使用 Stripe 运行订阅付款”扩展程序。
当我尝试为用户订阅计划时,我收到一条错误消息,提示“snap.data 不是函数”。我使用以下代码:
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 );
;
);
);
这是 Firebase 团队提供的代码示例的 .then 变体:
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 );
);
我的 await 函数出错,提示“未捕获的 SyntaxError:await 仅在异步函数中有效”。所以我将代码重构为 .then 变体。
当我从 button.addEventListener("click) 运行此代码时,我收到一条错误消息,提示 snap.data 不是函数。
我检查了 snap,它已被填充
客户在 Firestore 和 Stripe 仪表板中创建,客户会话被创建。
这里出了什么问题? Stackoveflow (Run Subscription Payments with Stripe Firebase Extension Webhook Not Firing) 上有一个类似的问题,但没有答案,所以我再试一次。
【问题讨论】:
【参考方案1】:您的查询:
db
.collection('customers')
.doc(cred.user.uid)
.collection('checkout_sessions')
可以一次获取多个文档。它产生的对象是 QuerySnapshot 类型的对象,可以在结果等中包含零个或多个文档。这就是你的snap
在这里——QuerySnapshot。您会注意到它没有data()
方法。这适用于 DocumentSnapshot 对象,您知道自己是否有一个文档。
如果您有 QuerySnapshot,则必须对其进行迭代以从中获取所有可能的文档快照,如 documentation 中所示。
但这似乎不是你想做的。您似乎想要访问之前使用 add()
添加的文档。如果这就是你想要的,你不应该像现在这样查询整个集合。只需找到您想要的单个文档和add a listener to it。
【讨论】:
感谢您的回复。我以为我并没有真正理解 sessionId 是什么,因为我从不查询 Firebase 团队编写的代码查询的方式。如果我按照您描述的方式查询数据库,“checkout_sessions 集合”中应该有一个“sessionsId”对象;但它不存在。 我在您在这里显示的代码中的任何地方都没有看到会话 ID,所以我不知道它应该来自哪里。我只看到一个引用文档字段的变量。不知道你期望它来自哪里。 我可以看到 sessionID 是从 snap.data() 中提取的,应该通过 Stripe 的 webhook 添加到 firebase 文档中。文档中没有 sessionID 可以找到。;这就是 Firebase 扩展文档所说的:“要为用户订阅特定的定价计划,请在 checkout_sessions 集合中为用户创建一个新文档。扩展将更新文档使用 Stripe Checkout 会话 ID,然后您可以使用该 ID 将用户重定向到结帐页面。" 我不确定是否真的可以使用此处的信息为您提供更多帮助。听起来您的实现中缺少某些内容。 感谢您的帮助。【参考方案2】:您需要收听您通过.add()
函数添加的特定文档的更新。此函数返回对该特定文档的引用:https://github.com/stripe/stripe-firebase-extensions/blob/next/firestore-stripe-subscriptions/POSTINSTALL.md#start-a-subscription-with-stripe-checkout
如果您不想/不能使用 async/await 语法,则需要从 .then()
函数获取该文档参考: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 );
);
);
【讨论】:
好吧,这很有道理。谢谢你的回答。以上是关于Firebase 扩展:使用 Stripe 运行订阅付款不会返回 sessionId的主要内容,如果未能解决你的问题,请参考以下文章
使用 Firebase 'Run Subscription Payments with Stripe' 扩展购买多个订阅
对如何在我的网络应用程序中使用 Stripe 作为 Firebase 的扩展感到困惑
使用 React Native/Stripe/Firebase 一次性付款
使用 Firebase JS SDK 版本 9 实施 Stripe 订阅
Firebase + stripe + react native 通知客户端 firebase 功能已完成
使用 Firebase HTTP 函数(Firebase、Stripe OAuth、React (JSX) 前端)将授权代码返回到 Stripe