升级Firebase至10.5.0后数据库/存储权限错误求助
Firebase 8.2.0升级至10.5.0后持续遭遇权限问题
我将Web应用的Firebase版本从8.2.0升级至10.5.0(采用Firebase官网提供的替代集成方案),此前代码无权限错误,但升级后一直碰到权限问题。
以下是我的upload.js文件:
import {initializeApp} from 'https://www.gstatic.com/firebasejs/10.5.0/firebase-app.js'; import { getStorage, ref as storageRef, uploadBytesResumable, getDownloadURL, } from 'https://www.gstatic.com/firebasejs/10.5.0/firebase-storage.js'; import {getAuth, onAuthStateChanged, signOut} from 'https://www.gstatic.com/firebasejs/10.5.0/firebase-auth.js'; import {getDatabase, ref as databaseRef, push, set} from 'https://www.gstatic.com/firebasejs/10.5.0/firebase-database.js'; // 以下配置信息已正确填写 const app = initializeApp({ apiKey: '', authDomain: '', databaseURL: '', projectId: '', storageBucket: '', messagingSenderId: '', }); const auth = getAuth(app); const database = getDatabase(app); const storage = getStorage(app); $('#addNew').on('submit', function (e) { e.preventDefault(); var file = $('#pic').prop('files')[0]; const fileExt = $('#pic').prop('files')[0].name.split('.').pop(); const fileName = `${getRandomString(15)}.${fileExt}`; var listStorageRef = storageRef(storage, `list/images/${fileName}`); var uploadTask = uploadBytesResumable(listStorageRef, file); uploadTask.on( 'state_changed', function (snapshot) { // 此处处理上传进度 }, function (error) { console.log(error); // 无日志输出 showMessageByID('发生未知错误。', '#message'); }, function () { getDownloadURL(listStorageRef).then(function (downloadURL) { const listRef = databaseRef(database, 'list'); const newRef = push(listRef); console.log(downloadURL); set(listRef, { name, // 此处还有其他数据 }) .then(function () { const id = newRef.key; // 此处还有其他操作 }) .catch(function (error) { console.log('错误对象:', error); // 未输出权限错误日志 showMessageByID(error.message, '#message'); // 此处会显示错误信息 }); }); }, ); });
我通过以下方式引入upload.js:
<script type="module" src="js/firebase/upload.js"></script>
数据库安全规则如下:
"list": { "$id": { ".write": "newData.child('createdBy').val() == auth.uid", ".read": false }, ".indexOn": "createdBy" },
问题排查与解决
数据库写入路径错误
当前代码调用push(listRef)生成了list下的新子节点newRef,但实际写入时却用set(listRef, ...)直接覆盖整个list节点,这既违反了只允许写入list/$id子节点的安全规则,还会丢失原有数据。同时,写入的数据未包含createdBy字段,无法满足规则中newData.child('createdBy').val() == auth.uid的校验要求。修正代码:
getDownloadURL(listStorageRef).then(function (downloadURL) { const listRef = databaseRef(database, 'list'); const newRef = push(listRef); // 获取当前登录用户 const user = auth.currentUser; if (!user) { showMessageByID('请先登录再操作', '#message'); return; } console.log(downloadURL); // 写入newRef节点而非listRef,并添加createdBy字段 set(newRef, { name, createdBy: user.uid, // 其他数据 }) .then(function () { const id = newRef.key; // 其他操作 }) .catch(function (error) { console.log('错误对象:', error); showMessageByID(error.message, '#message'); }); });前置校验用户登录状态
升级后的模块化API对权限校验更严格,需要确保执行数据库写入前用户已登录。可在表单提交事件开头添加校验:$('#addNew').on('submit', function (e) { e.preventDefault(); const user = auth.currentUser; if (!user) { showMessageByID('请先登录再操作', '#message'); return; } // 后续原有代码 });安全规则适配
现有规则已针对list/$id节点设置了正确的写入权限,只要修正写入路径并携带createdBy字段,规则就能正常生效,无需额外修改。
内容的提问来源于stack exchange,提问作者Cedric Hadjian
相关产品推荐
相关产品推荐

