May*_*ate 1 google-sheets firebase google-cloud-functions google-cloud-firestore
在使用 Cloud Firestore 作为数据后端时,我需要与非技术站点经理(编辑、销售团队等)共享一些数据集合。此外,我希望让这些人有权编辑存储在 Cloud Firestore 中的数据。
Google Sheets 是站点管理员非常熟悉的工具,它可以节省我开发 CRUD 管理面板的时间,例如从头开始用于数据更新和查看的界面。
这个 Stack Overflow答案显示了如何使用云函数和深度级别发送数据,这个 Github库可以使用 Google Apps 脚本从 Firestore 获取数据(我希望使用 Cloud Functions 或 Firebase Admin SDK 来做到这一点),但我仍在尝试弄清楚如何制作一个端到端的基于表格的界面。
请指导是否有更好的替代方案来实现相同的目标。我在从 SQL 数据库和 Django 自动创建的管理界面切换到 Firebase-Firestore NoSQL 世界时遇到了一些困难。
我了解您希望能够从 Google Sheet 调用 Cloud Functions 函数,以便为 Firestore 构建一个“基于端到端 Sheets 的界面”。
您可以使用UrlFetchApp类发出请求以获取HTTP Cloud Function的 URL 。
您的 Apps 脚本代码如下:
function callSimpleHTTPCloudFunction() {
const url = "https://xxxxxxxx.cloudfunctions.net/simpleHttp";
response = UrlFetchApp.fetch(url, {
method: 'get'
})
respObj = JSON.parse(response.getContentText());
Logger.log(respObj);
}
Run Code Online (Sandbox Code Playgroud)
虽然您的云功能会像:
exports.simpleHttp = functions.https.onRequest((req, res) => {
res.send({ msg: 'simpleHttp' });
});
Run Code Online (Sandbox Code Playgroud)
这是 Cloud Function 的一个非常简单的示例,但您可以调整此 Cloud Function 以从/向 Firestore 读取和写入数据。看看这个官方视频的起点:https : //www.youtube.com/watch?v=7IkUgCLr5oA&t=1s& list =PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM&index=3
现在,如果您想以一种可以控制谁可以通过 Cloud Function 访问您的数据的方式对您的用户进行身份验证,这将变得更加复杂。
有一个官方云函数示例,其中显示了“如何将 HTTPS 函数限制为仅适用于您应用的 Firebase 用户”:https : //github.com/firebase/functions-samples/tree/master/authorized-https-endpoint
如代码注释中所述:“Firebase ID 令牌需要作为授权 HTTP 标头中的承载令牌传递,如下所示:Authorization: Bearer <Firebase ID Token>。解码成功后,ID 令牌内容将添加为req.user。”
因此,您需要在 Apps 脚本代码中为 Firebase 用户生成 Firebase ID 令牌。为此,我们将使用Firebase Auth REST API。在此示例中,我们将使用在 Google 表格 ( Session.getActiveUser().getEmail()) 中通过身份验证的用户的电子邮件作为 Firebase 用户名。
如文档中所述,要调用 Firebase Auth REST API,您需要通过 Firebase 管理控制台中的项目设置页面获取 Firebase 项目的 Web API 密钥。
以下 Apps 脚本函数将完成这项工作:
function getToken() { {
const userName = Session.getActiveUser().getEmail();
const pwd = 'xyz' //For example get the password via a prompt.
//This is NOT the password of the account authenticated with Google Sheet, but the password of the Firebase user. In this example, the emails are the same but they are different accounts.
const verifyPasswordUrl = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=[API_KEY]" //Replace with your Web API Key
const payload = JSON.stringify({"email":userName,"password": pwd,"returnSecureToken": true});
const verifyPasswordResponse = UrlFetchApp.fetch(verifyPasswordUrl, {
method: 'post',
contentType: 'application/json',
muteHttpExceptions: true,
payload : payload
});
const token = JSON.parse(verifyPasswordResponse.getContentText()).idToken;
return token;
}
Run Code Online (Sandbox Code Playgroud)
然后,仍然在 Apps 脚本中,您在调用 Cloud Function 时使用令牌,如下所示:
function callSecuredHTTPCloudFunction() {
const authHeader = {"Authorization": "Bearer " + getToken()};
const url = "https://us-central1-<yourproject>.cloudfunctions.net/securedHttp/";
const response = UrlFetchApp.fetch(url, {
method: 'get',
headers: authHeader,
muteHttpExceptions: true,
});
Logger.log(response);
//Here do what you want with the response from the Cloud Function, e.g. populate the Sheet
}
Run Code Online (Sandbox Code Playgroud)
Cloud Function 代码如下,改编自官方示例。
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const cors = require('cors')({
origin: true
});
const express = require('express');
const cookieParser = require('cookie-parser')();
const app = express();
// Express middleware that validates Firebase ID Tokens passed in the Authorization HTTP header.
// The Firebase ID token needs to be passed as a Bearer token in the Authorization HTTP header like this:
// `Authorization: Bearer <Firebase ID Token>`.
// when decoded successfully, the ID Token content will be added as `req.user`.
const validateFirebaseIdToken = (req, res, next) => {
console.log('Check if request is authorized with Firebase ID token');
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith('Bearer ')
) {
console.error(
'No Firebase ID token was passed as a Bearer token in the Authorization header.',
'Make sure you authorize your request by providing the following HTTP header:',
'Authorization: Bearer <Firebase ID Token>'
);
res.status(403).send('Unauthorized');
return;
}
let idToken;
if (
req.headers.authorization &&
req.headers.authorization.startsWith('Bearer ')
) {
console.log('Found "Authorization" header');
// Read the ID Token from the Authorization header.
idToken = req.headers.authorization.split('Bearer ')[1];
console.log(idToken);
} else {
// No cookie
res.status(403).send('Unauthorized');
return;
}
admin
.auth()
.verifyIdToken(idToken)
.then(decodedIdToken => {
console.log('ID Token correctly decoded', decodedIdToken);
req.user = decodedIdToken;
return next();
})
.catch(error => {
console.error('Error while verifying Firebase ID token:', error);
res.status(403).send('Unauthorized');
});
};
app.use(cors);
app.use(cookieParser);
app.use(validateFirebaseIdToken);
app.get('/', (req, res) => {
res.send(`Your email is ${req.user.email}`);
});
// This HTTPS endpoint can only be accessed by your Firebase Users.
// Requests need to be authorized by providing an `Authorization` HTTP header
// with value `Bearer <Firebase ID Token>`.
exports.securedHttp = functions.https.onRequest(app);
Run Code Online (Sandbox Code Playgroud)
您可以很好地编写带有 POST 和有效负载的类似函数,以便将数据从 Google Sheet 发送到 Cloud Function,然后写入 Firestore。
最后,请注意,您可以实现相同的方法来从 Google Sheet调用Firestore REST API,而不是调用 Cloud Functions。
| 归档时间: |
|
| 查看次数: |
3195 次 |
| 最近记录: |