2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

我们弃用 Firebase 了

  • 2022-12-01
    北京
  • 本文字数:3353 字

    阅读完需:约 11 分钟

我们弃用 Firebase了

我们已经在 Firebase 上发布了 10 几款应用程序,几乎用到了该平台每个方面的特性,并设计了一个可以实现优雅扩展的手册。可以说,事实已经证明,Firebase 对 K-Optional Software 而言是非常宝贵的工具。


就在 2022 年 3 月,我们的开发人员还在为Firebase Extensions等创新欢呼。遗憾的是,过去几个月的三个主要变化破坏了开发体验,因此,在新项目中,K-Optional 将转向其他替代方案。

Firebase:好的地方


这个归谷歌所有的平台即服务(PaaS)使构建者做出了多项基础设施决策:内容交付网络、NoSQL 数据库事件处理程序和网络拓扑等等。的确,纯从性能上讲,在 AWS/Azure/ GCP 上构建的定制化原生服务包优于 Firebase 套件。但是,当我们考虑到开发时间和维护成本时,Firebase 通常是一个合乎逻辑的选择。


Firebase实时数据库最初给人的感觉相当具有革命性,特别是在WebSockets被广泛接受或Server-Sent Events出现之前。你可以编写实现实时数据同步的应用程序,而且不需要开发大量的传输逻辑。那些在自制即时通讯应用程序中使用了长轮询请求的的用户肯定会喜欢它。


事实上,Firebase 有许多方面是我们喜欢的:


  • 使用 Firestore,许多客户端状态管理方面的挑战都不复存在,特别是与数据新鲜度有关的问题。

  • 免费就可拥有的实时体验。

  • Firestore 的文档/集合架构:它迫使人们仔细考虑数据建模。它还反映了一个直观的导航方案。

  • Firestore 中的关系数据也是如此。与MongoDB不同,它不可能远程执行任何类似于 SQL 连接的操作。因此,开发人员必须接受 NoSQL 的精神,提前分发关系数据。

  • Firebase 套件可以帮助我们快速构建可扩展的原型,处理来自客户端的数据连接,在发布到生产环境之前强化安全规则,并对敏感逻辑使用 Firebase Functions。

  • 云Firestore安全规则写起来很有趣,在考虑客户端-服务器安全方面,这是一个可靠的模型。

  • 开箱即用的身份验证很不错。(不过,在我们看来,其内置的 Firebase 邮件验证体验很糟糕)。

  • 实际上,我们发现,在 CI/CD 方面,Firebase Hosting 比 AWS S3 + Cloudfront 更简单,因为它提供了一个简单的命令可以对存储库做这方面的设置。

Firebase:不那么好的地方


另一方面,Firebase 也有不少地方让我们犹豫:


  • Firebase 要求使用谷歌/GSuite 登录——我们喜欢分散我们的供应商和服务

  • Firebase Hosting 不提供细粒度的文件控制:你可以部署整个应用程序,也可以什么都不部署。也许不常见,但我们在静态页面生成和调试 CDN 问题上遇到了限制。

  • Firestore 索引的创建速度非常缓慢,而且不优雅,比创建同等的 Algolia 索引花费的时间要长得多。

  • 由于是闭源的,你不能默认以为 Firebase 始终存在(像Parse一样),依赖于特定的 API 版本也不可靠。

  • 因此,你也不能真正地在本地运行 Firebase。当然,也有Firebase模拟器,但它们很慢,也很难调试,而且普遍存在不足;经常会在负载不是很大的情况下出现意料之外的失败,而你可能期望有一个能够承受足够负载的、健壮的本地环境。

  • Firebase CLI 限制相当严格:

  • 对于像启用 Firestore 这么简单的事情,你也只能通过仪表板完成,而不能通过命令行。

  • firebase login:ci有意禁止传递认证密钥。我喜欢执行firebase login:ci | xargs -I {} gh secret set FIREBASE_TOKEN --body="{}" ,但唉,其前后都还有其他的命令。(见下面我们使用的一种丑陋的变通方案)附注:说到 Firebase CLI 的限制,下面是两个我们经常使用的解决方案,或许对你有用。

提取机器可读的 CI token

是的,我喜欢将 CI token 直接传递到我的秘密管理器。


citokenRaw=$(firebase login:ci)citoken=$(echo "$citokenRaw" | tail -n 3 | head -n 1)
复制代码

将 Web 配置加入.env 文件


下面这几行代码会下载一个 Firebase Web 片段,并将其转换为适合.env文件的内容。这个 Web 片段会将站点配置为使用特定的 Firebase 应用程序,并借助环境变量使我们可以跨项目保留脚手架。


# 丑陋 丑陋 丑陋 
fbKeysObject=$( firebase apps:list --project=$FB_PROJECT --non-interactive --json | fx '.result[0].appId' | xargs -I {} firebase apps:sdkconfig WEB {} | sed '/{/,/}/!d ' | sed -r 's/;|firebase.initializeApp|(|)//g' )
# 构建一个.env文件echo "$fbKeysObject" | jq '.projectId' | xargs -I {} echo "REACT_APP_FB_PROJECT_ID=""{}" > .envecho "$fbKeysObject" | jq '.appId' | xargs -I {} echo "REACT_APP_FB_APP_ID=""{}" >> .envecho "$fbKeysObject" | jq '.storageBucket' | xargs -I {} echo "REACT_APP_FB_STORAGE_BUCKET=""{}" >> .envecho "$fbKeysObject" | jq '.locationId' | xargs -I {} echo "REACT_APP_FB_LOCATION_ID=""{}" >> .envecho "$fbKeysObject" | jq '.apiKey' | xargs -I {} echo "REACT_APP_FB_API_KEY=""{}" >> .envecho "$fbKeysObject" | jq '.authDomain' | xargs -I {} echo "REACT_APP_FB_AUTH_DOMAIN=""{}" >> .envecho "$fbKeysObject" | jq '.messagingSenderId' | xargs -I {} echo "REACT_APP_FB_MESSAGE_SENDER_ID=""{}" >> .env
复制代码


附注结束。综上所述,Firebase 存在的大多数问题都来自谷歌所有权,们让我很恼火。而最近的事态发展引发了我们的反思……

不祥之兆

Firebase 近期的三个发展变化让我们确信,未来属于Supabase这样的工具。

GCP 偏向之一:通过移除 Firebase 的特性迫使人们迁移到 GCP

在过去的几个月中,Firebase 去掉了仪表板中的 Cloud Function 日志。如果需要,则可以通过他们提供的链接在 Google Cloud Console 仪表板中查看。



如果这可以定制,那对我来说会是一种帮助。


我还注意到,无法在 Firebase Storage 仪表板上下载文件了;必须导航到单独的 GCP 平台。



我无法在 Firebase 仪表板上下载这个文件。这不符合直觉,“打开”竟然不让我下载。



直接从 Google Cloud Console 下载。


GCP 似乎正在蚕食 Firebase 开发环境。


从运营的角度来看,这是合理的。但是,简化 Firebase 的云体验会使它失去大部分的价值;我们客户并不想了解 GCP。在最近的 Firebase 项目中,我在想我们是否应该推出自定义的服务。我相信,谷歌不会介意开发人员放弃 Firebase 而单纯使用 GCP。

近期 Cloud Function 部署的速率限制


Cloud Function CI/CD 降级。Firebase对Cloud Function部署强制执行每100秒80次调用的配额。据我所知,这个配额已经存在有一段时间了。


但最近,Cloud Function部署在达到这个配额后开始悄然失败。这很棘手,因为 80 个端点并不算多,而且Firebase至今没有提供一种简洁的方法,让我们可以只部署更改后的Cloud Function


对于这个问题,K-Optional Software 几乎在同一时间收到了多个关于项目(不是我们的项目)的咨询请求,一切都表明,是 API 的突然变化造成了麻烦。


我考虑了以下两种变通方法:


  1. 使用单个基于事件名称调用条件逻辑(如使用事件分派器)的 Cloud Function。那看起来像是一个名为dispatcherFunction的函数,根据eventName切换到相应内部函数的调用。

  2. 逐步形成一种约定,其中每个 Cloud Function 都对应于它自己的文件。在 CI 代码中,过滤掉未更改的文件,并部署与已更改的文件相对应的函数。不用说,这两种变通方法都有很多需要改进的地方。将路由逻辑塞进端点牺牲了可读性和 HTTP 层缓存,而且这种脚手架方法无助于现有的大型项目。

GCP 偏向之二


最后,Firebase 越来越多地引导用户使用 GCP 获取基本服务。在过去的几个月里,开发人员偶尔会反馈由于缺少权限而导致Firebase Hosting失败我们的团队上周也开始报告这个问题。为什么 Firebase Hosting 会需要 Cloud Function list 授权,这让我很困惑。无论如何,Google Cloud Console 是添加此权限的唯一方法。


尽管 Firebase 开发有所下降,但我最近还是经常在这个权限仪表板上看到自己。



根据Cloud Function部署文档:Firebase 错误只能在 Google Cloud 上解决。

Supabase

最近,作为考察过程的一部分,我们在 Supabase 上开发了一些小项目。其开发体验令人愉快,特别是行级安全,那与 Firestore 规则类似,但更为强大。Supabase 正基于 Deno 开发他们的无服务器函数套件,这表明他们对优秀的技术很重视。


我们喜欢 Supabase 使用的PostgreSQL。我们计划在可伸缩性方面做更多的研究,因为 SQL 数据库不能像 NoSQL 数据库那样增长。尽管如此,Supabase 来的正是时候。


声明:本文为 InfoQ 翻译,未经许可禁止转载。


原文链接:


https://koptional.com/article/why-we%E2%80%99re-moving-away-from-firebase

2022-12-01 15:466392
用户头像
刘燕 InfoQ高级技术编辑

发布了 1112 篇内容, 共 598.6 次阅读, 收获喜欢 1982 次。

关注

评论

发布
暂无评论
发现更多内容

阿里P8纯手写SQL文档:收获不止SQL优化抓住SQL的本质

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

Go- 结构体

HelloBug

Go 语言 结构体

Ubuntu Server 20.04 搭建安装Harbor

玏佾

Docker k8s Harbor

IntelliJ IDEA 中如何将 POM 中的版本号快速提出为属性

HoneyMoose

如何大规模交付高质量、高一致性的RESTful API及配套产物

刘宇

API OpenAPI REST API

RedHat 8 如何检查端口是否联通

HoneyMoose

【VueRouter 源码学习】第一篇 - 环境搭建与路由模式介绍

Brave

源码 vue-router 9月日更

Confluence 数据中心版本接近生命周期了

HoneyMoose

Go- 方法-2

HelloBug

方法 Go 语言

GitHub阅读量最高的文章竟是图解Java,不愧是Alibaba内部资料

Java~~~

Java 架构 面试 JVM 基础

世界顶级安全专家耗时三年写出了这份4308页的Linux笔记

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

大牛分享,献出这份年薪68W的蚂蚁金服Java高级开发封神宝典!

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

区块链落地进行时:专利猛增,构建工业互联网信任价值

CECBC

德勤:区块链成为现实,采用逐渐增多

CECBC

物联网实时监管 区块链云端留痕 公章何时何地何人用过一清二楚

CECBC

Go- 方法-1

HelloBug

方法 Go 语言

在线JSON转Go Struct工具

入门小站

工具

GraphQl Calculator计算指令@distinct:使用表达式对列表进行去重

杜艮魁

数据中台 graphql

软件工程师必备沟通技巧

俞凡

沟通 认知

华为顶级网络工程师分享出这份TCP/IP网络编程笔记!已封神

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

世界顶级安全专家整理出的这份笔记告诉你Linux应该怎么学

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

GitHub破百万访问的阿里神作:并发实现原理JDK源码笔记

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

09. 深度学习携手大数据引领第三AI热潮--何为深度学习?

Databri_AI

人工智能

Promise.all() 原理解析及使用指南

devpoint

Promise 异步任务 9月日更

大厂慌了!由国外技术工程师亲自操刀的微服务实战手册限时分享

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

🚄【Redis干货领域】从底层彻底吃透AOF原理(基础篇)

码界西柚

redis aof Redis 协议 9月日更

美团面试:请手写一个快排,被我怼了

程序员 面试 算法

发布半小时登上GitHub首页的Spring Boot实战笔记,竟是京东T8编写

Java~~~

Java spring 架构 面试 Spring Boot

阿里P8终于总结出这份SpringBoot分布式架构精髓笔记

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

Linux之ssh-add命令

入门小站

Linux

微信朋友圈高性能架构设计

毛先生

我们弃用 Firebase了_AI&大模型_John Considine_InfoQ精选文章