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