Nextjs/Stripe webhook 中的 Firebase 管理问题

问题描述 投票:0回答:1

我尝试在下一个js中使用stripe webhook,但每次都会收到此错误:

在此环境中无法检测到项目ID

我在应用程序路由器中尝试过,而不是切换到页面路由器(在我之前的项目中,它工作正常)。我尝试使用 admin.json 进行初始化,并尝试从单独的文件进行初始化。

项目信息已成功从env文件中提取。

网络钩子代码:

import * as admin from "firebase-admin";
import { timeConverter } from "@/utils/timeConverter"; // Assuming this utility is defined elsewhere in your project

import Stripe from "stripe";

const key = process.env.STRIPE_TEST_SECRET_KEY || "";

const stripe = new Stripe(key, {
  apiVersion: "2023-10-16",
});

// Initialize Firebase Admin SDK
if (!admin.apps.length) {
  console.log("FIREBASE_PROJECT_ID:", process.env.FIREBASE_PROJECT_ID);
  console.log("FIREBASE_CLIENT_EMAIL:", process.env.FIREBASE_CLIENT_EMAIL);

  admin.initializeApp({
    credential: admin.credential.cert({
      projectId: process.env.FIREBASE_PROJECT_ID,
      clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
      privateKey: process.env.FIREBASE_PRIVATE_KEY!.replace(/\\n/g, "\n"),
    }),
  });
}

const db = admin.firestore();

export const config = {
  api: {
    bodyParser: false, // Disable body parsing
  },
};

export default async function webhook(req: any, res: any) {
  if (req.method !== "POST") {
    return res.status(405).send("Method Not Allowed");
  }

  const data: any = await new Promise((resolve, reject) => {
    let rawBody = "";
    req.on("data", (chunk: any) => {
      rawBody += chunk;
    });
    req.on("end", () => {
      resolve(rawBody);
    });
    req.on("error", (err: any) => {
      reject(err);
    });
  });
  const sig = req.headers["stripe-signature"];

  let event;
  try {
    event = stripe.webhooks.constructEvent(
      data,
      sig,
      process.env.STRIPE_WEBHOOK_KEY!
    );
  } catch (err: any) {
    console.error(`Webhook Error: ${err.message}`);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }
  const eventType = event.type;
  const session = event.data.object;
  switch (eventType) {
    case "invoice.payment_failed":
      console.log("Invoice payment failed");

      await handleInvoicePaymentFailed(session);
      break;

    case "invoice.paid":
      console.log("Invoice payment successful", session);

      await handleInvoicePaid(session);
      break;

    case "customer.subscription.deleted":
      console.log("Subscription deleted");
      await handleSubscriptionDeleted(session);
      break;

    default:
      console.log(`Unhandled event type ${eventType}`);
  }

  res.json({ received: true });
}

async function handleInvoicePaymentFailed(session: Stripe.Invoice) {
  const userId =
    session.subscription_details &&
    session.subscription_details.metadata &&
    session.subscription_details.metadata.userId;

  if (userId) {
    const usersRef = db.collection("users");
    const snapshot = await usersRef.where("uid", "==", userId).get();

    if (!snapshot.empty) {
      snapshot.forEach(async (doc) => {
        await usersRef.doc(doc.id).update({
          subscriptionStatus: "Not active",
        });
      });
    }
  }
}

async function handleInvoicePaid(session: Stripe.Invoice) {
  console.log({ session });

  const userId =
    session.subscription_details &&
    session.subscription_details.metadata &&
    session.subscription_details.metadata.userId;
  // const userId = "randomId132456798";

  console.log({ userId });

  if (userId) {
    try {
      // const db = admin.firestore();
      const usersRef = db.collection("users");
      console.log(0);
      const snapshot = await usersRef.where("uid", "==", userId).get();
      console.log(0.5, snapshot.size);

      const subscription = await stripe.subscriptions.retrieve(
        session.subscription as string
      ); // Cast to string if necessary

      console.log(1, { subscription });

      const interval = subscription.items.data[0].price.recurring?.interval;
      console.log(2);

      const subscriptionId = subscription.id;

      console.log("subscription from invoice paid", subscription);
      const productId: any = subscription.items.data[0].price.product;
      const product = productId && (await stripe.products.retrieve(productId));
      const productName = product && product.name;
      const subStatus = subscription.status;
      const price =
        subscription.items.data[0].price.unit_amount &&
        subscription.items.data[0].price.unit_amount / 100;

      console.log({ productName });

      if (!snapshot.empty) {
        snapshot.forEach(async (doc) => {
          await usersRef.doc(doc.id).update({
            subscriptionStatus: subStatus,
            subscriptionId: subscriptionId,
            startDate: timeConverter(subscription.current_period_start),
            endDate: timeConverter(subscription.current_period_end),
            customerId: subscription.customer,
            subType: interval,
            productName: productName,

            amount: price,
          });
        });
      }
    } catch (err) {
      console.log("err", err);
    }
  }
}

async function handleSubscriptionDeleted(subscription: any) {
  console.log({ subscription });
  const userId = subscription && subscription.metadata.userId;

  console.log({ userId });
  // Update the Firestore document for the user with the matching userId
  if (userId) {
    const usersRef = db.collection("users");
    const snapshot = await usersRef.where("uid", "==", userId).get();

    if (!snapshot.empty) {
      snapshot.forEach(async (doc) => {
        await usersRef.doc(doc.id).update({
          subscriptionStatus: "deleted",
        });
      });
    }
  }
}
node.js firebase next.js stripe-payments firebase-admin
1个回答
0
投票

已解决:问题是 firebase 已经使用 firebase-adapter 进行了初始化,但我不知道,因为这是一个客户端项目,

我删除了管理初始化,只是从 firebase 初始化的文件中导入了 firestore

问题是:重复初始化

© www.soinside.com 2019 - 2024. All rights reserved.