線上體驗 Live Demo:https://410355-collab.github.io/Premium-Business-Calculator/
(強烈建議使用 iPhone Safari 或 Android 手機開啟體驗!)
GitHub 開源倉庫:https://github.com/410355-collab/Premium-Business-Calculator
歡迎提出建議與指導
(開發環境:Google Antigravity IDE + Google Gemini 協同開發)
在使用各類 Web 應用程式或輕量化記帳工具時,最令人崩潰的體驗莫過於精心設定好的客製化偏好與歷史紀錄,只要一換手機、清除瀏覽器快取或開啟無痕模式,所有資料就瞬間化為烏有。雖然部分工具提供了「匯出 JSON / 匯入 JSON」的備份功能,但要求使用者每次改動後都手動下載備份檔,不僅操作極其繁瑣,也違背了現代 Web 應用應具備的流暢體驗。
為了讓高階商務計算機達到原生 App 級別的資料持久化與跨裝置體驗,我們在 firebase-sync.js 模組中建構了一套「本機優先(Local-First)與無感靜默同步」的雲端資料架構。使用者只需透過熟悉的 Google 帳號一鍵彈窗授權,系統便會在背景自動將地端的十六項核心商務狀態與 Firestore 雲端資料庫保持即時鏡像同步。
現代 Web 應用的身份驗證介面應儘可能降低使用者的操作門檻。我們採用 Firebase Auth 的彈窗驗證機制 (signInWithPopup),讓使用者無需記憶額外的帳號密碼,點擊即可完成身分確認。
// firebase-sync.js 登入與 Auth 狀態變化監聽
function initSyncUI() {
const loginContainer = document.getElementById('cloud-sync-status-card');
if (!loginContainer) return;
// 實時監聽使用者登入狀態
auth.onAuthStateChanged((user) => {
currentUser = user;
updateSyncUI(user);
if (user) {
// 登入成功後自動同步雲端資料並與本地融合
syncFromCloud(user.uid);
}
});
}
function handleGoogleLogin() {
const provider = new firebase.auth.GoogleAuthProvider();
auth.signInWithPopup(provider).catch((error) => {
console.error("Google Login Error:", error);
if (error.code !== 'auth/popup-closed-by-user') {
alert("Google 登入失敗: " + error.message);
}
});
}
登入完成後,系統會自動在設定選單頂部渲染出使用者的 Google 個人頭像,並附帶動態微光閃爍的在線同步圓點(.online-sync-dot),直觀提示使用者當前資料已處於雲端保護與同步狀態下。
前端直接呼叫 Firebase 或 Gemini API 時,前端代碼中的 API Key 無可避免會暴露在瀏覽器端。若未加上保護機制,金鑰極易遭有心人士擷取並濫用配額。
為了確保開源倉庫的安全性與配額控管,我們在 Google Cloud Console / Firebase 後台設置了嚴格的「網站限制(HTTP Referrer 限制)」。僅允許預設白名單內的特定域名向 API 金鑰發起請求:
http://127.0.0.1/* 與 http://localhost/*(保障開發與測試不受影響)。https://410355-collab.github.io/Premium-Business-Calculator/(確保唯有官方部署的 GitHub Pages 正式站點才能合法發送要求)。透過這道安全護城河,即使開源倉庫中包含金鑰設定,外人也無法在第三方網頁或腳本中盜刷我們的 API 請求與 Firebase 資源。
計算機的雲端同步絕非僅僅備份計算結果,而是必須將使用者在整個應用程式中的所有行為習慣全數復原。我們封裝了包含歷史紀錄、自訂按鍵配置、快照設定、主題色彩與稅率在內的十六項關鍵 key。
// 雙向同步的十六項核心 localStorage Key
const SYNC_KEYS = [
'bCalc_history', // 歷史計算與記帳明細
'bCalc_keyboard_layout', // 自訂按鍵佈局
'bCalc_keyboard_snapshots',// 按鍵快照庫
'bCalc_theme_color', // 佈景主題色彩
'bCalc_light_mode', // 深淺色模式
'bCalc_decimals', // 小數點顯示位數
'bCalc_tax_rates', // 自訂稅率設定
'bCalc_percent_mode', // 百分比模式
'bCalc_haptic', // 觸控震動反饋
'bCalc_large_number_format',// 大數格式化
'bCalc_category_bubble', // 分類膠囊顯示
'bCalc_curr_from', // 來源貨幣
'bCalc_curr_to', // 目標貨幣
'bCalc_tax_excluded', // 未稅/含稅預設值
'bCalc_font_style', // 字體風格
'bCalc_lang' // 介面多國語系
];
當使用者在一台裝置上修改了預設稅率或替換了鍵盤主題,這些變更會以 JSON 字典的型態完整封裝並寫入 Firebase Cloud Firestore 中的使用者專屬 Document 中,達成跨平台 100% 的狀態還原。
在開發雲端同步功能時,若要重構整個專案中數百處寫入 localStorage 的呼叫點,代價極為高昂且容易遺漏。為了在不破壞既存程式碼的前提下實現自動同步,我們採用了 Monkey Patching(猴子補丁) 技術,對瀏覽器原生的 localStorage.setItem 進行了優雅的函數覆寫。
// 覆寫原生 localStorage.setItem 實現自動防抖上傳
const originalSetItem = localStorage.setItem;
localStorage.setItem = function (key, value) {
// 執行原生的本地寫入操作,確保離線優先
originalSetItem.apply(this, arguments);
// 若寫入的 key 屬於應用程式資料(帶有 bCalc_ 前綴),自動觸發雲端同步
if (key && key.startsWith('bCalc_')) {
window.triggerCloudSync();
}
};
window.triggerCloudSync = function () {
if (currentUser) {
// 1 秒 Debounce 防抖:避免連續按鍵時進行高頻冗餘的網路請求
if (window._cloudSyncTimer) clearTimeout(window._cloudSyncTimer);
window._cloudSyncTimer = setTimeout(() => {
syncToCloud(currentUser.uid);
}, 1000);
}
};
這種設計帶給使用者極致流暢的無感體驗。當使用者在計算機上連續點擊按鈕或調整設定時,本地 localStorage 會在 0 毫秒內即時響應;而在使用者停止操作後的 1 秒鐘內,攔截器會自動發起一次併購更新,將所有變更靜默推送到雲端,兼顧了地端的高效響應與雲端的高可靠性。
當使用者在新裝置登入或重新開啟網頁時,系統會發起 syncFromCloud 讀取作業。演算法會比對雲端時間戳記與地端資料的差異,若發現雲端有更新的資料,會自動更新本地 localStorage,並無縫觸發介面重繪。
// 雲端資料拉取與 UI 熱重載
async function syncFromCloud(uid) {
if (!uid) return;
try {
const doc = await db.collection('users').doc(uid).get();
if (doc.exists) {
const cloudData = doc.data();
let needReload = false;
SYNC_KEYS.forEach(key => {
if (cloudData[key] !== undefined) {
const localVal = localStorage.getItem(key);
if (localVal !== cloudData[key]) {
localStorage.setItem(key, cloudData[key]);
needReload = true;
}
}
});
// 首次登入但本地已有歷史資料:自動進行首登雲端備份
if (!cloudData.bCalc_history && localStorage.getItem('bCalc_history')) {
await syncToCloud(uid);
} else if (needReload) {
// 資料更新後,無縫觸發前端 UI 熱重載,免手動重新整理網頁
if (typeof window.renderCustomKeyboard === 'function') window.renderCustomKeyboard();
if (typeof window.renderHistory === 'function') window.renderHistory();
if (typeof window.applyTheme === 'function') window.applyTheme();
}
} else {
// 新使用者帳號:自動將本地預設設定備份至雲端
await syncToCloud(uid);
}
} catch (err) {
console.error("Fetch Cloud Sync Error:", err);
}
}
透過這套冷啟動與熱重載機制,使用者在手機上記錄的消費明細與自訂佈局,會在開啟桌面瀏覽器的瞬間完美呈現,完全無需手動重新整理網頁,徹底實現了跨裝置無縫銜接的「精品級商務計算機」終極目標。
經過 29 天的極客漫征,我們從第一天零基礎建構算術解析引擎、FLIP 像素級對調動畫、幾何外幣感應、多模型 Gemini 降級鏈,一路推進到了今天的 Firebase 跨裝置無感雲端同步。
明天是這趟旅程的最終章。我們將帶大家進行 30 天的極客開發總結,分享如何運用 Antigravity IDE 與 Gemini 協同完成 3,600 多行純原生程式碼,並公開開源專案的未來展望!