如何在Firebase V9实时数据库提交表单后实时获取数据并优化写入?
Firebase V9实时数据库:表单新增访客后的数据展示与优化写入方式
我想实现两个需求:
- 使用Firebase V9实时数据库,每次通过表单新增访客后,从数据库获取数据并展示在表格中;
- 想知道有没有比当前用
set和ref更简便的数据写入方式。
现有代码
HTML
<body> <form class="form"> <span>Guest name:</span> <input type="text" name="name" id="name"><br> <span>Guest surname:</span> <input type="text" name="surname" id="surname"><br> <span>Tel:</span> <input type="number" name="tel" id="tel" maxlength="16"><br> <span>Country:</span> <input type="text" name="country" id="country"><br> <span>Arrival date:</span> <input type="date" name="arrivalDate" id="arrivalDate"><br> <span>Departure date:</span> <input type="date" name="departureDate" id="departureDate"><br><br> <input type="submit" value="Send"> </form> <p class="success"></p> </body>
jQuery
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-app.js"; const firebaseConfig = { apiKey: "hidden", authDomain: "hidden", databaseURL: "hidden", projectId: "reservations-32294", storageBucket: "reservations-32294.appspot.com", messagingSenderId: "773498700596", appId: "1:773498700596:web:618889de8423f066071b61" }; // Initialize Firebase const app = initializeApp(firebaseConfig); import { getDatabase, ref, set } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-database.js"; const db = getDatabase(); function insertData() { set(ref(db, "Guests/" + $("#name").val() + " " + $("#surname").val()), { Name: $("#name").val(), Surnam: $("#surname").val(), Tel: $("#tel").val(), Country: $("#country").val(), ArrivalDate: formatDate($("#arrivalDate").val()), DepartureDate: formatDate($("#departureDate").val()) }) .then(() => { $(".success").html("Success!").fadeIn("fast"); setTimeout(function() { $('.success').fadeOut('fast'); }, 2000); $("input").removeAttr("disabled"); }) .catch(error => alert(error)); } $(".form").submit(function(e) { e.preventDefault(); $("input").attr("disabled", "true"); insertData(); }); const formatDate = (date) => { const newDate = date.split("-"); let day = newDate[2]; let month = newDate[1]; let year = newDate[0]; let newFormat = `${day}.${month}.${year}.`; return newFormat; }
一、更简便的数据写入方式
你当前的写法存在两个问题:一是同名访客会覆盖数据,二是手动逐个获取表单值繁琐。推荐以下优化方案:
1. 使用push生成唯一ID(避免数据覆盖)
Firebase的push方法会自动生成随机唯一ID作为节点键,彻底解决同名覆盖问题,写法更简洁:
首先导入push方法:
import { getDatabase, ref, push } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-database.js";
然后修改insertData函数:
function insertData() { // 统一收集表单数据 const guestData = { Name: $("#name").val(), Surname: $("#surname").val(), // 修正原代码中键名拼写错误(Surnam→Surname) Tel: $("#tel").val(), Country: $("#country").val(), ArrivalDate: formatDate($("#arrivalDate").val()), DepartureDate: formatDate($("#departureDate").val()) }; // 用push自动生成节点并写入数据 push(ref(db, "Guests"), guestData) .then(() => { $(".form")[0].reset(); // 新增:清空表单 $(".success").html("Success!").fadeIn("fast"); setTimeout(() => $('.success').fadeOut('fast'), 2000); $("input").removeAttr("disabled"); }) .catch(error => alert(error)); }
2. 自动收集表单数据(简化取值逻辑)
如果表单字段较多,用serializeArray自动收集数据,无需手动逐个取值:
function getFormData() { const formData = $(".form").serializeArray(); const data = {}; formData.forEach(item => { // 统一字段名首字母大写格式 const key = item.name.charAt(0).toUpperCase() + item.name.slice(1); // 日期字段单独格式化 data[key] = (item.name === "arrivalDate" || item.name === "departureDate") ? formatDate(item.value) : item.value; }); return data; } // 改造insertData函数 function insertData() { const guestData = getFormData(); push(ref(db, "Guests"), guestData) .then(() => { $(".form")[0].reset(); $(".success").html("Success!").fadeIn("fast"); setTimeout(() => $('.success').fadeOut('fast'), 2000); $("input").removeAttr("disabled"); }) .catch(error => alert(error)); }
二、新增访客后获取数据并展示在表格中
需要先添加表格容器,再编写数据渲染逻辑,支持实时更新或单次刷新两种模式:
1. 修改HTML,添加表格
在<p class="success"></p>后添加表格结构:
<table id="guestsTable" border="1" style="margin-top:20px; width:100%; border-collapse:collapse;"> <thead> <tr> <th>姓名</th> <th>姓氏</th> <th>电话</th> <th>国家</th> <th>到达日期</th> <th>离开日期</th> </tr> </thead> <tbody id="guestsBody"> <!-- 数据将渲染到这里 --> </tbody> </table>
2. 编写表格渲染函数
创建函数负责将数据库数据转换为表格行:
function renderGuests(guests) { const tbody = $("#guestsBody"); tbody.empty(); // 清空现有内容 if (!guests) { tbody.html("<tr><td colspan='6' style='text-align:center;'>暂无访客数据</td></tr>"); return; } // 遍历所有访客数据生成表格行 Object.values(guests).forEach(guest => { const row = `<tr> <td>${guest.Name}</td> <td>${guest.Surname || guest.Surnam}</td> <!-- 兼容原代码的拼写错误 --> <td>${guest.Tel}</td> <td>${guest.Country}</td> <td>${guest.ArrivalDate}</td> <td>${guest.DepartureDate}</td> </tr>`; tbody.append(row); }); }
3. 实时监听数据库变化(自动更新表格)
导入onValue方法,实时监听Guests节点的所有数据变化,新增、修改、删除数据时表格自动更新:
import { getDatabase, ref, push, onValue } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-database.js"; // 初始化后添加监听逻辑 onValue(ref(db, "Guests"), (snapshot) => { const guestsData = snapshot.val(); renderGuests(guestsData); });
4. (可选)仅在新增成功后刷新表格
如果不需要实时监听,仅在提交表单后刷新一次表格,可在insertData的成功回调中主动读取数据:
import { getDatabase, ref, push, get } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-database.js"; // 修改insertData的then回调 .then(async () => { $(".form")[0].reset(); $(".success").html("Success!").fadeIn("fast"); setTimeout(() => $('.success').fadeOut('fast'), 2000); $("input").removeAttr("disabled"); // 主动读取数据并渲染表格 const snapshot = await get(ref(db, "Guests")); const guestsData = snapshot.val(); renderGuests(guestsData); })
内容的提问来源于stack exchange,提问作者russelhd
相关产品推荐
相关产品推荐

