计划firebase身份验证:使用pubsub导出到bucket

chhkpiq4  于 2023-08-07  发布在  其他
关注(0)|答案(3)|浏览(92)

我正在尝试使用pubsub将firebase auth:export调度到bucket中。我的目的是每天备份auth(firebase auth:export的输出对于我的目的来说是完全好的)。
这是我尝试的pubsub:

const functions = require('firebase-functions')
const exec = require("child_process").exec

const datetime = new Date();
const formattedDate = datetime.toISOString().slice(0,10)

const commandString = `firebase auth:export auth_export_${formattedDate}.json --format=JSON && \
gsutil -m cp -r auth_export_${formattedDate}.json gs://backup_firebase_auth_daily && \
rm auth_export_${formattedDate}.json`

exports.scheduledFirebaseAuthExport = functions.pubsub
    .schedule('every 24 hours')
    .onRun(() => {
        return exec(commandString, (error, stdout, stderr) => {
            if (error) {
                console.log(`error: ${error.message}`);
                process.exit();
                return;
            }
            if (stderr) {
                console.log(`stderr: ${stderr}`);
                process.exit();
                return;
            }
            console.log(stdout);
            process.exit();
        });
    });

字符串
但我得到了以下错误:
/bin/sh: 1: firebase: not found
我假设这是因为我不能在运行pubsub的任何环境中运行命令行脚本。
使用Google Cloud API或firebase获得firebase认证的任何其他方法都是受欢迎的。

vmjh9lq9

vmjh9lq91#

我假设这是因为我不能在运行pubsub的任何环境中运行命令行脚本。
事实上,你不能在云函数中执行命令行脚本(既不是Firebase CLI命令,也不是gsutil命令),云函数是你的代码运行的“环境”(这里的Pub/Sub是mechanism that triggers云函数)。
另一方面,由于“Firebase CLI也可以作为标准Node模块以编程方式使用”,如此处所述,您可以通过Cloud Function执行CLI的部分命令。
请注意,上面的单词“some”是粗体的,因为正如在同一个Github页面中所解释的那样:
注意:当在受限环境(如Cloud Functions)中使用时,并非所有firebase-tools命令都能以编程方式工作,因为它们需要访问本地文件系统。
这正是auth:export命令的情况,该命令“将活动项目的用户帐户导出到JSON或CSV文件”。
因此,不幸的是,不可能通过云函数自动执行此命令。
使用Google Cloud API或firebase获得firebase认证的任何其他方法都是受欢迎的。
一种方法是使用Admin SDK:您可以批量检索整个用户列表,例如将其存储在受保护的Firestore集合(或任何其他存储解决方案)中。这可以从云函数(例如scheduled Cloud Function)或您拥有的运行Node.js,Java,Python等的服务器触发。

1tuwyuhd

1tuwyuhd2#

正如其他答案已经指出的那样,您可以使用云函数将Auth文件导出到带有auth.export()的临时路径。然后,在同一个函数中,您可以将该文件上传到存储桶。整个过程可能看起来像这样:

const {Storage} = require("@google-cloud/storage");
const client = require("firebase-tools");
const split = require("split");
const path = require("path");
const os = require("os");
const fs = require("fs");

exports.scheduledExportAuthData = functions.pubsub.schedule("every 24 hours")
    .onRun(async (context) => {
      // Google Cloud data
      const projectId = "your_firebase_project_id";
      const bucketName = "your_google_cloud_bucket";

      // Path parameters
      const exportPathPrefix = "authExports/authExport_";
      const currentDate = admin.firestore.Timestamp.now().toDate();
      const exportPath = exportPathPrefix + currentDate.toISOString().split("T")[0] + ".json";
      const tempPath = path.join(os.tmpdir(), path.basename(exportPath));

      // Init Storage
      const storage = new Storage();
      const bucket = storage.bucket(bucketName);

      // Export Auth file in temporary path
      await client.auth
          .export(tempPath, {project: projectId})
          .catch( (error) => console.log(`Error exporting Auth data: ${error}`));

      // Uploading the auth file to the GC bucket
      await bucket
          .upload(tempPath, {
            destination: exportPath,
          })
          .catch( (error) => console.log(`Error uploading Auth file: ${error}`));

      // Once the file has been uploaded delete the temporary file to free up disk space.
      fs.unlinkSync(tempPath);
    });

字符串
但是,我不知道这种方法在大型数据库中的性能如何。
此外,您还可以删除存储桶中超过X天的导出文件。你可以在同一个(或其他)函数中完成,在末尾添加这样的内容:

exports.scheduledExportAuthData = functions.pubsub.schedule("every 24 hours")
    .onRun(async (context) => {
      
      .....
    
      // Delete Auth exports older than 14 days
      const expirationDays = 14;
      // Lists files in the bucket filtered by the export path prefix
      // and delete them the last modified date meets the criteria
      const options = {
      prefix: exportPathPrefix,
      };
      const [files] = await bucket.getFiles(options);
      files.forEach( (file) => {
        const fileDate = file.updated;
        if ((currentDate-fileDate)/86400000 > expirationDays) { 
          bucket.file(file.name)
              .delete()
              .catch( (error) => console.log(`Error deleting Auth file: ${error}`));
        }
      });
    });


除了使用最后一段代码,您还可以删除旧的导出,在您的存储桶中添加对象生命周期规则。例如,要删除超过14天的auth导出,您可以使用捕获中的配置:Google Cloud Bucket Lifecycle Configuration

5tmbdcev

5tmbdcev3#

firebase-tools现在提供auth.export()功能。请参见回购
请参见此处的云函数的示例实现:Backup firebase users

import * as tools from 'firebase-tools'

 // Export users to a temporary file
 await tools.auth.export(path, { project: projectId })

字符串

相关问题