
教程文档示例工程【免费下载链接】website-archiveArchive of the Coding Train website (first version)项目地址https://gitcode.com/gh_mirrors/we/website-archive点击查看免费下载本篇文章围绕《Programming with Text》课程第 9.3 节的核心主题展开如何用纯客户端 JavaScript 从 FirebaseGoogle 提供的 Database-as-a-Service 云数据库中检索数据。文章以“高分榜high score list”为实战示例结合本仓库 9-03 示例源码 逐行拆解ref.on(value)实时监听、data.val()数据快照、Object.keys()遍历等关键 API并延伸对比once()一次性读取与 Coding Challenge #45 中的完整检索链路读完你将能独立实现“保存 → 实时检索 → 动态渲染列表”的完整数据闭环。从数据库即服务DBaaS说起在纯浏览器端 JavaScript 应用中传统做法很难持久化数据localStorage只能存本机自建服务器又需要后端代码。Firebase 提供了“数据库即服务Database as a Service”方案——你不需要部署任何服务器直接在前端代码里读写云端数据库。本系列课程 9.1 节引入了这一概念对应文档 9.1-what-is-firebase-database-as-a-service.md9.2 节演示了如何把数据写入 Firebase对应文档 9.2-firebase-saving-data.md 与源码 9-02 保存示例而本篇文章要解决的正是数据闭环的另一半——如何把存进去的数据读出来。课程本身属于“Programming from A to Z”ITP 课堂强调以客户端 JavaScript 单枪匹马完成完整的网络应用。应用场景一个最简单的高分榜本节的演示场景是一个迷你游戏点击按钮加分输入昵称initials后提交分数到 Firebase同时页面上实时显示所有人的分数列表。这个例子说明“高分榜”只是载体Firebase 检索到的数据可以是任何东西——文字、JSON 对象、嵌套数组甚至是完整的一幅画后文 Coding Challenge #45 会看到。先看完整页面骨架 9-03 的 index.htmlhtml head meta charsetUTF-8 script languagejavascript typetext/javascript srchttps://cdn.jsdelivr.net/npm/p51.4.1/lib/p5.min.js/script script typetext/javascript srchttps://www.gstatic.com/firebasejs/3.6.3/firebase.js/script script languagejavascript typetext/javascript srcsketch.js/script /head body div idgame/div ol idscorelist/ol /body /html页面做了三件关键事情引入 p5.js负责画布与 UI 元素创建引入 Firebase 客户端 SDK版本为 3.6.3通过script标签全局加载定义两个容器#game用于承载游戏画布与控件#scorelist是一个有序列表ol高分榜条目将动态插入其中。初始化把应用“连”上 Firebase 数据库在 sketch.js 的setup()中首先用 p5.js 创建画布和输入控件随后是连接 Firebase 的关键代码var config { apiKey: AIzaSyDsJ73sg9CjbMj08ibW8KuTYQ4WfV3faSM, authDomain: my-not-awesome-project.firebaseapp.com, databaseURL: https://my-not-awesome-project.firebaseio.com, storageBucket: my-not-awesome-project.appspot.com, messagingSenderId: 583703514528 }; firebase.initializeApp(config); database firebase.database();config对象各字段的含义与作用配置项作用apiKey标识你的 Firebase 项目注意纯前端场景下它并非不可见的“密钥”真正的读写安全靠数据库安全规则rules控制authDomain认证域名用于登录鉴权流程databaseURL核心字段Realtime Database 的 REST 访问地址形如https://项目名.firebaseio.comstorageBucket云存储Storage桶地址本例未使用messagingSenderId消息推送发送者 ID本例未使用firebase.initializeApp(config)完成全局初始化随后firebase.database()拿到数据库实例。此配置与 9.2 保存数据示例 9-02 的 sketch.js 完全一致——保存和检索共用同一套初始化逻辑这也是“一个项目、一个数据库、读写两端”的标准形态。从源码结构看示例里的项目名为my-not-awesome-project实际使用时务必替换为你自己在 Firebase 控制台创建的项目信息。核心 API用ref.on(value)实时监听数据连接数据库后检索动作只有短短几行var ref database.ref(scores); ref.on(value, gotData, errData);这行代码是本节真正的技术核心理解它需要拆成三层database.ref(scores)返回指向数据库中scores节点的引用Reference。数据在 Firebase 中按 JSON 树形结构组织scores下的每个子节点就是一条以push()生成的唯一 key 标识的高分记录。ref.on(value, ...)注册一个实时监听器。只要scores节点下的任何数据发生变化新增、修改、删除回调都会自动触发并把当前节点的**完整数据快照DataSnapshot**传给你。这是 Firebase Realtime Database 与普通 HTTP 请求最大的区别不需要手动轮询云端一有变化页面立即收到推送。第三个参数errData错误处理回调监听失败或权限不足时会被调用。数据快照本身需要通过.val()方法取出 JavaScript 原生对象。监听回调gotData的完整实现如下function gotData(data) { // 1. 先清空旧的列表 DOM var scorelistings selectAll(.scorelisting); for (var i 0; i scorelistings.length; i) { scorelistings[i].remove(); } // 2. 取出数据并遍历 key var scores data.val(); var keys Object.keys(scores); for (var i 0; i keys.length; i) { var k keys[i]; var initials scores[k].initials; var score scores[k].score; // 3. 动态生成列表项 var li createElement(li, initials : score); li.class(scorelisting); li.parent(scorelist); } }这段代码里藏着三个容易被忽略的实战细节细节一先清空再重建。因为on(value)每次返回的是整个节点的最新完整快照而不是“增量”所以最稳妥的渲染策略是先用selectAll(.scorelisting)找到上一次渲染的所有条目并remove()再重新生成列表。这样可避免重复叠加也保证了列表与数据库永远一致。细节二Object.keys()遍历的是 Firebase 自动生成的 key。高分数据在 9.2 节是用ref.push(data)写入的参见 9-02 的 submitScorepush()会为每条记录生成一个全局唯一、按时间递增的随机 key形如-Kxxxxxx...因此这里用scores[k].initials、scores[k].score按 key 取值。细节三p5.js 的 DOM 方法。createElement(li, text)、li.class(...)、li.parent(scorelist)是 p5.js 提供的 DOM 操作接口它们让“数据 → 页面元素”的转换可以在不写原生document.createElement的情况下完成这也是本课程选择 p5.js 的原因之一。配套的写入端完整闭环如何形成检索之所以有意义前提是数据已经被写入。同一示例中的submitScore()展示了与检索对称的写入逻辑function submitScore() { var data { initials: initialInput.value(), score: score }; var ref database.ref(scores); var result ref.push(data); console.log(result.key); }ref.push(data)把{initials, score}追加为scores下的新子节点并返回带.key的结果对象。当这条数据写入云端后ref.on(value)的监听器会立刻被触发——保存端与检索端因此自动联动只要任意一个浏览器提交了高分所有正在打开页面的用户都会在同一时刻看到列表刷新这就是“实时”二字的来源。错误处理回调errData在检索端同样必要function errData(err) { console.log(Error!); console.log(err); }在实际项目中这里应替换为向用户展示友好提示的逻辑例如“无权访问该节点”或“网络异常”而不仅仅是打印到控制台。从“持续监听”到“一次性读取”on与once的取舍ref.on(value, ...)适合需要持续同步的场景高分榜、聊天室、协作白板。但有些场景只需要读一次比如用户点击某条记录才加载它的详情。此时应使用ref.once(value, ...)它只触发一次回调后即自动解除监听。仓库中 Coding Challenge #45把 p5.js 绘画保存到 Firebase 同时示范了这两种读法是本节内容最完整的延伸案例列表页用on(value)持续监听把drawings节点下所有绘画的 key 渲染成可点击的链接列表var ref database.ref(drawings); ref.on(value, gotData, errData);点击某条记录时用once(value)精准读取function showDrawing(key) { if (key instanceof MouseEvent) { key this.html(); } var ref database.ref(drawings/ key); ref.once(value, oneDrawing, errData); function oneDrawing(data) { var dbdrawing data.val(); drawing dbdrawing.drawing; } }这个例子还展示了两个重要技巧路径可以下钻database.ref(drawings/ key)直接定位到某个具体子节点不必每次读取整个集合存储结构化数据一条绘画记录保存的是{name, drawing}其中drawing是包含若干路径每条路径又是{x, y}点序列的嵌套数组——印证了本节文档中的那句话“数据可以是任何东西”。对比可见on与once的选择标准很简单页面生命周期内需要随数据库变化而自动更新就用on只关心当前时刻的一次性结果如点击加载详情、初始化时取一次配置就用once还能省去不必要的监听开销。安全与版本注意事项结合源码有两点需要在实践中特别注意apiKey不是访问令牌。示例中 API Key 直接写在config里这是 Firebase 前端 SDK 的标准用法但它只能标识项目。真正的数据保护依赖 Firebase 控制台里的Realtime Database 安全规则rules——例如只允许已认证用户读写scores节点。仓库示例为了教学便利未配置鉴权生产环境务必补上规则。SDK 版本以仓库为准。本仓库示例统一通过script srchttps://www.gstatic.com/firebasejs/3.6.3/firebase.js加载 3.x 版本 SDK见 9-03 index.html 与 CC_045 index.html。Firebase 后续版本9.x 起改为模块化 API初始化与检索写法有差异复现代码时需按对应版本查阅官方文档。小结检索 Firebase 数据的标准三步把本节内容压缩成可复用的方法论任何“读取 Firebase 数据”的需求都逃不开三步初始化firebase.initializeApp(config)firebase.database()取引用database.ref(节点路径)定位要读的数据节点注册回调持续同步用ref.on(value, success, error)一次性读取用ref.once(value, success, error)在成功回调里用data.val()取数据、Object.keys()遍历、再同步渲染 DOM。从本课程系列课程总览见 _learning/programming-with-text/index.mdSession 9 目录见 README的演进看这节内容为后续“数据驱动前端应用”打下了基础保存端9.2解决“怎么写”检索端9.3解决“怎么读”而 Coding Challenge #45 则把读写合并验证了纯前端应用也能完成“云端持久化 实时分发”的完整数据流。掌握本节的三步模型再配合on/once的取舍与安全规则意识你就能在自己的 p5.js 项目中自由存取任意结构的数据了。赞分享教程文档示例工程【免费下载链接】website-archiveArchive of the Coding Train website (first version)项目地址https://gitcode.com/gh_mirrors/we/website-archive点击查看免费下载相关推荐p5.js 函数参数与实参用参数化函数实现代码复用Code! Programming with p5.js 第 5.2 章实战p5.js 函数参数与实参用参数化函数实现代码复用Code! Programming with p5.js 第 5.2 章实战 本指南围绕 Coding教程文档示例工程p5.js 弹跳小球用条件语句实现边界反弹动画Code! Programming with p5.js 第 3.2 讲p5.js 弹跳小球用条件语句实现边界反弹动画Code! Programming with p5.js 第 3.2 讲 本文基于 Coding Train教程文档示例工程在 p5.js 中用 for 循环遍历数组Coding Train《Code! Programming with p5.js》7.2 实战解析在 p5.js 中用 for 循环遍历数组Coding Train《Code! Programming with p5.js》7.2 实战解析 数组Arra教程文档示例工程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考