通过 REST API,从 Javascript 中的 Firebase 云函数中对 Firebase 实时数据库进行经过身份验证的浅层读取

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

在 firebase 云函数中,我需要读取 Firebase RTDB 中的位置。

我只想要浅读,即键列表,而不是该位置下的整个数据库树。我可以通过 REST API 轻松做到这一点if该位置在未经授权的情况下通常可读。

https://DATABSEID.firebaseio.com/PATH/IN/DATABASE.json?shallow=true

但是我需要数据库的这个位置通常不允许读取。在我的 Firebase Cloud 函数 index.js 的其他部分,我可以使用 Firebase Admin SDK 对任何位置进行各种读取和写入,覆盖数据库规则中设置的任何内容。

遗憾的是,当我的云函数调用 REST API 时,我没有这种自由。当它调用 REST API 时,它似乎总是未经身份验证。它可以获取全局可访问的信息,但我还没有弄清楚如何从我没有全局访问的位置“/PATH/IN/DATABASE”读取。

const fetch = require("node-fetch");
const cors = require("cors")({ origin: true });
const admin = require("firebase-admin");
const functions = require("firebase-functions");
const serviceAccount = require("./serviceAccount.json");


async function doShallowRead() {
const idToken = await admin.auth().createCustomToken("Shallow-Reader");
const response = await fetch(
    "https://DATABSEID.firebaseio.com/PATH/IN/DATABASE.json?shallow=true",
    {
      headers: {
        Authorization: `Bearer ${idToken}`,
        "Content-Type": "application/json",
      },
    }
  );

  console.log(
    "Response was ",
    JSON.stringify(response)
  );                                      // Response was {"size":0,"timeout":0}
  const shallow = await response.json();
  console.log(JSON.stringify(shallow))    // {"error":"Unauthorized request."}
...
}


exports.callMyFunction = functions.https.onCall(
  async (/*data, context */) => {
    await doShallowRead();
    console.log("OK")
  }
);


我尝试了上面的方法,但我收到上面的错误消息,即“未经授权的请求”

我也试过这个获取idToken,结果还是一样

const idToken = await admin.credential.applicationDefault().getAccessToken();

这很令人沮丧,我正在疯狂阅读文档并转圈。谁能帮忙?

javascript firebase firebase-authentication google-cloud-functions
2个回答
0
投票

一个可能的解决方案是使用 Identity Platform REST API,更准确地说是

signInWithPassword
端点。

您使用在 Firebase Auth 服务中声明的用户的用户名和密码(当然还有对您的 RTDB 具有所需访问权限的用户)调用它,您将在响应负载中获得一个 ID 令牌。

然后,在调用 RTDB REST API 时,您需要将 ID Token 作为 auth= 查询字符串参数传递,如 doc 中所述。


0
投票

你没有做任何你的服务帐户,这是验证的关键。

import * as admin from 'firebase-admin';
import * as serviceAccountObject from './serviceAccount.json';

const serviceAccount = serviceAccountObject as admin.ServiceAccount;
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
});
© www.soinside.com 2019 - 2024. All rights reserved.