简体   繁体   English

尝试通过 Next.js API 路由上的 admin.firestore.v1.FirestoreAdminClient 导出备份。 错误:无法加载默认凭据

[英]Trying to export backup via admin.firestore.v1.FirestoreAdminClient on a Next.js API route. Error: Could not load the default credentials

I'm trying to run this code to implement a Firestore backup.我正在尝试运行此代码来实现 Firestore 备份。

But for the first time, I'm deploying it into a Next.js project.但这是我第一次将其部署到 Next.js 项目中。

I'll hit it on my /api/backup endpoint.我将在我的/api/backup端点上点击它。

const backupHandler: NextApiHandler = async (req,res) => {
  try {
  
    const admin = initializeFirebaseAdmin();
    const PROJECT_ID = getProjectId();
    
    const client = new admin.firestore.v1.FirestoreAdminClient();
    const DB_NAME = client.databasePath(PROJECT_ID, '(default)');

    const TODAY = getToday();  // YYYY-MM-DD
    const hashId = generateId().slice(0,5);
    const BUCKET = `gs://${PROJECT_ID}.appspot.com`;
    const FOLDER = `firestore-backup/${TODAY}-${hashId}`;
    const FULL_PATH = `${BUCKET}/${FOLDER}`;

    await client.exportDocuments({
      name: DB_NAME,
      outputUriPrefix: FULL_PATH,
      collectionIds: [] // CAN LIST SPECIFIC COLLECTIONS
    });

    console.log(`Backup successfully exported`);
    return res.status(200).send("Ok");
    
  }
  catch(err) {
    console.log(err);
    return res.status(500).send("Server error");
  }
  
};

This is the initializeFirebaseAdmin() function这是initializeFirebaseAdmin() function

type FirebaseAdmin = typeof import("firebase-admin/lib/firebase-namespace")

const getServiceAccount = () : admin.ServiceAccount => {
  if (process.env.VERCEL_ENV === "production"
  ||  process.env.VERCEL_GIT_COMMIT_REF === "staging")  {
    return SERVICE_ACCOUNT.PROD;
  }
  else return SERVICE_ACCOUNT.TEST;
};

export const initializeFirebaseAdmin = (): FirebaseAdmin => {
  const account = getServiceAccount();  // THIS GETS THE SERVICE ACOUNT (VIA THE DOWNLOADED .json FILE)
  const PROJECT_ID = getProjectId();
  if (!admin.apps.length) {
    admin.initializeApp({
      credential: admin.credential.cert(account),
      databaseURL: `https://${PROJECT_ID}.firebaseio.com`  // I TRIED WITH AND WITHOUT THIS LINE: SAME RESULT
    });
  }
  return admin;
};

This is the error I'm getting:这是我得到的错误:

Error: Could not load the default credentials.错误:无法加载默认凭据。 Browse to https://cloud.google.com/docs/authentication/getting-started for more information.浏览到https://cloud.google.com/docs/authentication/getting-started了解更多信息。 at GoogleAuth.getApplicationDefaultAsync (/var/task/node_modules/google-auth-library/build/src/auth/googleauth.js:173:19)在 GoogleAuth.getApplicationDefaultAsync (/var/task/node_modules/google-auth-library/build/src/auth/googleauth.js:173:19)

在此处输入图像描述

At first I was just using the credential property.起初我只是使用credential属性。 Then I added the databaseURL to see if it would solve the issue, but still, same result.然后我添加了databaseURL以查看它是否可以解决问题,但仍然是相同的结果。

I think I'm initializing the firebase-admin properly.我想我正在正确初始化firebase-admin Not sure what is going wrong here.不知道这里出了什么问题。


UPDATE: Just found out that this very same code works fine on my local environment (in development), but does not work on my Next.js Node.js environment when I deploy it.更新:刚刚发现这个相同的代码在我的本地环境(开发中)上运行良好,但在我部署它时不适用于我的 Next.js Node.js 环境。 What could be going wrong?可能出了什么问题?

After days in hell, just found out what I was doing wrong.在地狱里待了几天之后,才发现我做错了什么。

I'm using new admin.firestore.v1.FirestoreAdminClient();我正在使用new admin.firestore.v1.FirestoreAdminClient(); because firebase-admin itself won't expose any methods for us to access the exportDocuments() functionality.因为firebase-admin本身不会公开任何方法让我们访问exportDocuments()功能。

But the fact is, when you instantiate the FirestoreAdminClient like that, it will not have access to the credentials that you've used on admin.initializeApp({credentials}) .但事实是,当您像这样实例化FirestoreAdminClient时,它将无法访问您在admin.initializeApp({credentials})上使用的凭据。

So you need to pass the credentials to the client, by doing:因此,您需要通过执行以下操作将凭据传递给客户端:

import * as admin from "firebase-admin";  // OR IMPORT IT FROM SOME SINGLETON initializeFirebaseAdmin FUNCTION
import { NextApiHandler } from "next";
import SERVICE_ACCOUNT from "some-path/serviceAccount.json";

interface CredentialBody { // COPIED THIS FROM google-auth-library > auth > credentials
  client_email?: string;
  private_key?: string;
}

const backupHandler: NextApiHandler = async (req,res) => {

  const client = new admin.firestore.v1.FirestoreAdminClient({
    credentials: SERVICE_ACCOUNT as CredentialBody    // <<<<<< THIS IS THE IMPORTANT PART
  });

  const PROJECT_ID = getProjectId();
  const DB_NAME = client.databasePath(PROJECT_ID, "(default)");

  const TODAY = getToday();  // YYYY-MM-DD
  const hashId = generateId().slice(0,5);
  const BUCKET = `gs://${PROJECT_ID}.appspot.com`;
  const FOLDER = `backup/${TODAY}-${hashId}`;
  const FULL_PATH = `${BUCKET}/${FOLDER}`;

  await client.exportDocuments({
    name: DB_NAME,
    outputUriPrefix: FULL_PATH,
    collectionIds: [] // CAN LIST SPECIFIC COLLECTIONS
  });

  console.log(`Backup successfully exported`);
  return res.status(200).send("Ok");

};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Dialog api v2 - 获取应用程序默认凭据时出现意外错误:无法加载默认凭据 - Dialog api v2 - Unexpected error while acquiring application default credentials: Could not load the default credentials 带有 IP 地址的 Next.js api 路由 - Next.js api route with IP address 如何为我的 next.js 项目导出 firebase firestore - How to export firebase firestore for my next.js project admin.auth().verifyIdToken(idToken) 错误:在 8.0.0 之后无法使用 firebase-admin 加载默认凭据 - admin.auth().verifyIdToken(idToken) Error: Could not load the default credentials whith firebase-admin after to 8.0.0 为什么我的 Next.js SSR api 在 Object 处调用错误:默认导出不是页面中的 React 组件:“/api/twilio”? - Why does my Next.js SSR api call Error: The default export is not a React Component in page:"/api/twilio" at Object.renderToHTML & how do I make work? 在 Next.js API 路由中进行外部 API 调用时遇到错误 - Encountered error when making external API call in Next.js API Route Next.js API 路由无法设置cookie - Next.js API route can't set cookie Next.js API 路由默认响应错误或没有 HTTP 方法匹配 - Next.js API routes default response on error or no HTTP method match 如何在 Next.js 中的 API 路由中获取 URL 查询字符串? - How to get URL query string in API route in Next.js? 无法使用 Next.js API 路由连接 Postgresql - Cannot connect Postgresql with Next.js API Route
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM