Firebase Cloud Function存储权限问题及ES模块导入服务账号疑问
Firebase Cloud Function 写入Storage权限错误及ES模块导入问题
错误现象
执行云函数时触发Storage权限错误:
Firebase Storage: User does not have permission to access 'Audio/English/United_States-OED-0/winter.mp3'. (storage/unauthorized)
模拟器和云端环境均出现该错误,Storage中无文件写入,代码中的Uploaded a string!日志也未输出。
ES模块导入服务账号失败
拥有Firebase IAM服务账号,知晓CommonJS模块可通过require导入,但当前函数为ES模块(使用import),尝试以下代码导入服务账号失败:
import serviceAccount from "./my-awesome-project-firebase-adminsdk-12345.json" assert { type: "json" };
原因是assert语法仅在Node 17及以上版本支持,而Firebase Functions使用Node 16。
云函数代码
import { initializeApp } from "firebase/app"; import * as functions from "firebase-functions"; import { getStorage, ref, uploadString, connectStorageEmulator } from "firebase/storage"; const firebaseConfig = { apiKey: ..., authDomain: ..., databaseURL: ..., projectId: ..., storageBucket: "my-awesome-project.appspot.com", appId: "..." }; const app = initializeApp(firebaseConfig); import got from 'got'; export const Oxford_T2S = functions.firestore.document('Users/{userID}/English/OED_T2S_Request').onUpdate((change, context) => { const storage = getStorage(app); connectStorageEmulator(storage, "localhost", 9199); // 注释此行切换到云端Storage const audioEnglishOEDWinterRef = ref(storage, 'Audio/English/United_States-OED-0/winter.mp3'); async function getOED() { try { let file = await got('https://audio.oxforddictionaries.com/en/mp3/winter__us_2.mp3'); uploadString(audioEnglishOEDWinterRef, file).then((snapshot) => { console.log('Uploaded a string!'); }); } catch (error) { console.error(error); } } return getOED() });
云端Storage规则
service firebase.storage { match /b/{bucket}/o { // 所有依赖request.auth.token的规则基于userLogin云函数 match /Audio/{shortLangA}/{file=**} { // 允许可信用户或对应语言教师写入音频文件,规则递归生效 allow write: if (request.auth.token.trusted || shortLangA in request.auth.token.teaches); } match /Users/{file=**} { // 允许写入发音测试 // 此规则存在安全风险 // 需优化为仅允许用户写入自身文件夹 allow read, write: if true; } match /{allPaths=**} { // 仅授权用户可读取存储桶 allow read: if request.auth != null; } } }
模拟器Storage规则
已将firebase init functions生成的默认规则中的false改为true,但问题仍未解决:
rules_version = '2'; service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if true; } } }
已尝试的操作
- 启动Angular项目并登录,无效果
got请求音频文件未抛出错误
内容的提问来源于stack exchange,提问作者Thomas David Kehoe
相关产品推荐
相关产品推荐

