news 2026/8/24 8:22:48

Minimus云存储揭秘:Firestore天气应用按用户隔离城市列表的完整教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Minimus云存储揭秘:Firestore天气应用按用户隔离城市列表的完整教程

Minimus云存储揭秘:Firestore天气应用按用户隔离城市列表的完整教程

【免费下载链接】minimus🌦️ A fully featured production ready Angular weather app (tutorial)项目地址: https://gitcode.com/gh_mirrors/mi/minimus

Minimus 是一款功能完整、可直接上生产的 Angular 天气应用(weather app),它的核心玩法是"关注你关心的城市"——而这份城市列表并不存在浏览器本地,而是存放在云端 Firestore 数据库中,按用户(uid)隔离存储,登录任何设备都能同步。这篇文章将带你快速看懂它的设计思路与实现细节,新手也能轻松上手。

🌐 什么是 Minimus 天气应用?

Minimus 用 Angular 搭建了一个完整的生产级天气应用,包含这几大能力:

能力说明
天气查询接入天气 API,展示城市温度与状态
城市关注从各国首都列表中挑选城市并"添加"到个人列表
用户体系Firebase Auth 提供注册 / 登录,会话状态由前端守卫保护
云端存储Firestore 按用户隔离保存城市列表,跨设备同步
PWA 支持Service Worker 注册,支持离线与安装

模块组织清晰,与云存储直接相关的目录如下:

  • 数据服务:src/app/services/fb/fb.service.ts
  • 城市列表页:src/app/pages/home/home.component.ts
  • 添加城市页:src/app/pages/add/add.component.ts
  • 路由与守卫:src/app/app-routing.module.ts、src/app/guards/app.guard.ts

🔗 整体架构:城市列表数据流全景

一次"关注城市"操作的完整数据流非常简单:

  1. 注册 / 登录:登录组件 和 注册组件 调用FbServicesignin/signup,背后是 Firebase 认证;
  2. 登录成功:跳转首页,HomeComponentngOnInit中调用fb.getCities(),用async管道把订阅到的城市渲染成一张张天气卡片;
  3. 添加城市AddComponent调用fb.addCity(),把{name, added}写入 Firestore;
  4. 云端落地:所有读写都发生在FbService内部,页面组件完全不感知存储细节——服务层是唯一接触 Firestore 的地方,这是它值得学习的架构习惯。

Firestore 按用户隔离存储城市列表

🏛️ 设计核心:用 uid 作为文档路径实现按用户隔离

这是全文最关键的一点。Firestore 采用"集合 - 文档"的分层结构,Minimus 的做法是:把用户的 uid 直接当作顶层文档路径,每个用户天然拥有一个独立的数据空间:

Firestore └── {uid: "aB3x..."} ← 用户A 的专属文档(路径即 uid) ├── Rome → { name: "Rome", added: "2026-08-23..." } └── Tokyo → { name: "Tokyo", added: "2026-08-23..." } └── {uid: "Kd9y..."} ← 用户B 的专属文档,与A完全隔离 └── Paris → { name: "Paris", added: "..." }

为什么这样设计好?

  • 零配置的权限隔离:不用手工建"users"集合再嵌套子集合,路径本身就是租户边界,用户 A 的查询永远只落在自己的文档里;
  • 读写路径最短:读取整份列表是一次read(uid),写入一座城市是一次write(uid/name),各只需一条路径;
  • 天然覆盖更新:城市名作为子键再次写入时直接覆盖,天然支持"取消关注再重新关注"。

在 fb.service.ts 中,核心实现只有两个方法:

getCities() { return this.auth.uid().pipe(switchMap((uid) => { return this.fs.read(`${uid}`); })); } addCity(name: string) { return this.auth.uid().pipe(switchMap((uid) => { return this.fs.write(`${uid}/${name}`, {name, added: new Date()}) .pipe(first()); }), first()); }

配合响应式操作符,两行思路就能说清:

  • auth.uid()是一个流,登录状态就绪后才发出 uid,未登录时根本不会发起任何读请求;
  • switchMap把"拿到 uid"无缝衔接成"按 uid 读 / 写",形成认证 → 存储的自动流水线;
  • first()让写操作在拿到首次结果后即完成订阅,避免多余往返。

🚦 路由守卫:云存储的双重门卫

再好的隔离也需要前端兜底。Minimus 用两个极简守卫在路由层完成"谁能进哪扇门"(见 app-routing.module.ts):

页面守卫行为
首页 / 详情 / 添加AppGuard未登录 → 强制跳/login
登录 / 注册AuthGuard已登录 → 踢回首页,避免重复登录

两个守卫都只依赖FbService.isAuth()这一个方法,逻辑清晰:云数据区需要门票,门票区不欢迎已有门票的人。这对新手是很好的守卫设计范本——守卫只做判断与跳转,不做业务。

⚙️ 配置指南:Firebase 密钥放在哪里

项目没有把密钥写死在组件里,而是遵循 Angular 的环境文件约定:

  • 开发环境:src/environments/environment.ts 中预留了apiKeyauthDomainprojectId等字段占位;
  • 生产环境:src/environments/environment.prod.ts 由构建时的fileReplacements自动替换。

应用启动时,在 app.module.ts 中通过AngularFireLite.forRoot(environment.config)一次性完成 Firebase 初始化——认证与 Firestore 客户端(AngularFireLiteAuthAngularFireLiteFirestore)由此注入到FbService中。

💡 小贴士:仓库里的环境文件默认是空占位符,动手前请填入你自己 Firebase 项目的配置,这是教程型仓库的常见做法。

✅ 新手可复用的设计清单

从 Minimus 的 Firestore 城市列表设计中,可以带走这几条经验:

  1. 按 uid 建文档路径——用登录态天然完成多租户隔离,不依赖复杂权限规则起步;
  2. 服务层收敛存储细节——组件只调业务方法(getCities/addCity),不直接碰数据库;
  3. 认证流驱动数据流——uid()+switchMap让"登录后才读数据"成为代码结构本身,而非运行时 if 判断;
  4. 路由守卫分层——AppGuard保护数据页,AuthGuard反制已登录用户,两个小文件覆盖全站安全;
  5. 环境文件管理密钥——开发与生产配置分离,密钥不进组件代码。

🚀 快速上手:动手跑一遍

如果你已经配置好 Angular CLI,可以克隆仓库并填入 Firebase 配置后启动:

git clone https://gitcode.com/gh_mirrors/mi/minimus cd minimus npm install npm start

打开首页注册一个账号,再添加一座城市,然后换一个浏览器重新登录——你会看到同一份城市列表出现在两个环境里。那一刻,你就真正理解了"Firestore 按用户隔离存储"的完整闭环。🎉

【免费下载链接】minimus🌦️ A fully featured production ready Angular weather app (tutorial)项目地址: https://gitcode.com/gh_mirrors/mi/minimus

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/24 8:22:20

美赛D题深度复盘:如何将团队合作量化建模与策略优化

1. 从“团队合作”到“数据驱动”:一次美赛D题的深度复盘2020年的美国大学生数学建模竞赛(MCM/ICM)D题,题目是“Teamwork Strategies: How to Build a Winning Team”。这个题目乍一看,似乎是一个偏重管理、社会科学的…

作者头像 李华
网站建设 2026/8/24 8:19:20

美赛B题建模实战:从沙堡持久性问题看交叉学科建模心法

1. 项目概述:从一道题看一场竞赛的底层逻辑又到了美赛季,后台和社群里关于B题的讨论又热了起来。2020年的美赛B题,题目是“The Longest Lasting Sandcastle”,翻译过来叫“最持久的沙堡”。乍一看,这题目有点“离谱”&…

作者头像 李华
网站建设 2026/8/24 8:18:08

C++函数模板深度解析:从泛型编程原理到工程实践避坑指南

1. 项目概述:从“重复造轮子”到“一劳永逸”的思维跃迁在C开发中,你有没有经历过这样的场景?你需要写一个max函数,用来比较两个整数的大小,于是你写下了int max(int a, int b) { return a > b ? a : b; }。过一会…

作者头像 李华
网站建设 2026/8/24 8:17:14

SDC命令详解:使用set_max_transition命令进行约束

相关阅读 SDC命令详解https://blog.csdn.net/weixin_45791458/category_12931432.html?spm1001.2014.3001.5482 目录 指定最大转换时间值 指定数据路径 指定时钟路径 指定对象列表/集合 Multicorner-Multimode支持 简单使用 写在最后 set_max_transition命令用于设置最大转换…

作者头像 李华
网站建设 2026/8/24 8:16:40

AI代码助手静默语义失败:成因剖析与防御实践指南

1. 项目概述:当代码助手“自信地”犯错“Confident and Wrong: Silent Semantic Failures in Coding Agents”,这个标题精准地戳中了当前AI编程助手(如GitHub Copilot、Amazon CodeWhisperer、Cursor等)使用体验中一个令人不安却又…

作者头像 李华
网站建设 2026/8/24 8:16:32

DeepResearch-9K:AI智能体深度研究能力的标准化评估基准

1. 项目概述:为什么我们需要一个“深度研究”的基准测试?最近在AI研究圈子里,一个词被反复提及:Agent。无论是大厂发布会还是开源社区的新项目,似乎不提“智能体”就落伍了。但热闹归热闹,一个根本性的问题…

作者头像 李华