Firebase 使用云功能的Firestore自动备份?

Firebase 使用云功能的Firestore自动备份?,firebase,google-app-engine,cron,google-cloud-firestore,firebase-admin,Firebase,Google App Engine,Cron,Google Cloud Firestore,Firebase Admin,Firebase docs建议您部署一个应用程序引擎应用程序来处理firestore的自动导出 app.js const axios = require('axios'); const dateformat = require('dateformat'); const express = require('express'); const { google } = require('googleapis'); const app = express(); // Trigger a back

Firebase docs建议您部署一个应用程序引擎应用程序来处理firestore的自动导出

app.js

const axios = require('axios');
const dateformat = require('dateformat');
const express = require('express');
const { google } = require('googleapis');

const app = express();

// Trigger a backup
app.get('/cloud-firestore-export', async (req, res) => {
  const auth = await google.auth.getClient({
    scopes: ['https://www.googleapis.com/auth/datastore']
  });

  const accessTokenResponse = await auth.getAccessToken();
  const accessToken = accessTokenResponse.token;

  const headers = {
    'Content-Type': 'application/json',
    Authorization: 'Bearer ' + accessToken
  };

  const outputUriPrefix = req.param('outputUriPrefix');
  if (!(outputUriPrefix && outputUriPrefix.indexOf('gs://') == 0)) {
    res.status(500).send(`Malformed outputUriPrefix: ${outputUriPrefix}`);
  }

  // Construct a backup path folder based on the timestamp
  const timestamp = dateformat(Date.now(), 'yyyy-mm-dd-HH-MM-ss');
  let path = outputUriPrefix;
  if (path.endsWith('/')) {
    path += timestamp;
  } else {
    path += '/' + timestamp;
  }

  const body = {
    outputUriPrefix: path
  };

  // If specified, mark specific collections for backup
  const collectionParam = req.param('collections');
  if (collectionParam) {
    body.collectionIds = collectionParam.split(',');
  }

  const projectId = process.env.GOOGLE_CLOUD_PROJECT;
  const url = `https://firestore.googleapis.com/v1beta1/projects/${projectId}/databases/(default):exportDocuments`;

  try {
    const response = await axios.post(url, body, { headers: headers });
    res
      .status(200)
      .send(response.data)
      .end();
  } catch (e) {
    if (e.response) {
      console.warn(e.response.data);
    }

    res
      .status(500)
      .send('Could not start backup: ' + e)
      .end();
  }
});

// Index page, just to make it easy to see if the app is working.
app.get('/', (req, res) => {
  res
    .status(200)
    .send('[scheduled-backups]: Hello, world!')
    .end();
});

// Start the server
const PORT = process.env.PORT || 6060;
app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});
package.json

{
  "name": "solution-scheduled-backups",
  "version": "1.0.0",
  "description": "Scheduled Cloud Firestore backups via AppEngine cron",
  "main": "app.js",
  "engines": {
    "node": "8.x.x"
  },
  "scripts": {
    "deploy": "gcloud app deploy --quiet app.yaml cron.yaml",
    "start": "node app.js"
  },
  "author": "Google, Inc.",
  "license": "Apache-2.0",
  "dependencies": {
    "axios": "^0.18.0",
    "dateformat": "^3.0.3",
    "express": "^4.16.4",
    "googleapis": "^38.0.0"
  },
  "devDependencies": {
    "prettier": "^1.16.4"
  }
}

cron.yaml

cron:
- description: "Daily Cloud Firestore Export"
  url: /cloud-firestore-export?outputUriPrefix=gs://BUCKET_NAME[/PATH]&collections=test1,test2
  target: cloud-firestore-admin
  schedule: every 24 hours
问题

但我想知道,使用HTTP云功能和云调度程序是否可以实现同样的效果

此应用程序引擎代码中是否有我无法通过HTTP云功能复制或访问的内容?我的意思是,这里真的需要应用程序引擎项目吗

注意:这不是一个基于意见的问题,
也不是太广泛。我想知道我是否需要应用程序引擎来实现这种行为,以及为什么

显然,我不需要将它设置为express服务器。只是一个普通的HTTP云函数,当调用该函数时,执行导出操作

我想在云调度程序中添加如下cron作业:


如果您使用云调度程序触发执行备份的功能,则根本不需要App Engine。

谢谢,道格!那么,我将介绍云函数。你介意分享一下你编写的云函数的代码吗?我也有同样的需要和挣扎it@JeremyBelolo我已经把它贴在你的问题上了。