- 开发工具
- 后端
【免费下载链接】firebase-js-sdk
Firebase Javascript SDK
导读
@firebase/storage-types是 Firebase JS SDK 中专门承载 Cloud Storage 公共 TypeScript 类型声明的纯类型包,其 CHANGELOG.md 记录了从 0.3.13 到 0.8.5 的完整版本演进。本文以这份变更日志为线索,结合同仓库的 index.d.ts、public-types.ts 与测试用例,逐条还原每个版本背后的真实代码变更——包括useEmulator/connectStorageEmulator模拟器支持、mockUserToken安全规则测试令牌、StorageError实例判断修复、TypeScript 升级等,帮助读者既看清"改了什么",也明白"为什么改、底层怎么实现"。
注意:根据 README.md,本包不面向直接使用,仅应通过官方
firebase包间接使用;当前仓库中它作为@firebase/storage-compat的 peer 依赖存在(见 storage-compat/package.json)。
一、这个包是什么:纯类型包与版本演进全貌
@firebase/storage-types的发布物只有一个文件index.d.ts(见 package.json),它只导出类型、不包含任何运行时逻辑,作用是为 Firebase Storage 的公共 API 提供稳定的 TypeScript 契约。其 peer 依赖为@firebase/app-types@0.x与@firebase/util@1.x(package.json),说明类型定义依赖 app 与 util 两个基础包的类型。
从 CHANGELOG 可以梳理出这条清晰的时间线:
| 版本 | 类型 | 核心变更 |
|---|---|---|
| 0.3.13 | Patch | 允许 Observer 类 API 省略回调(修复 #3224) |
| 0.4.0 | Minor | 新增storage().useEmulator()模拟器方法(PR #4346) |
| 0.4.1 | Patch | 更新 peerDependencies(修复 #4789) |
| 0.5.0 | Minor | 实现 Storage 的mockUserToken并修复 JWT 格式问题(PR #5282) |
| 0.6.0 | Minor | 发布模块化 SDK(PR #5345,修复 #5015) |
| 0.6.1 / 0.7.0 | Patch/Minor | TypeScript 升级至 4.7.4(PR #6682 / #6799) |
| 0.8.0 | Minor | 修复用户无法用instanceof StorageError判断错误的问题(PR #6974) |
| 0.8.1 | Patch | 统一各包repository.url为 NPM 偏好格式(PR #8079) |
| 0.8.2 | Patch | 全包 bump 以配合 staging 流程(PR #8237) |
| 0.8.3 | Patch | TypeScript 升级至 5.5.4(PR #8604) |
| 0.8.4 / 0.8.5 | Patch | 更新依赖与顶层 devDependencies(PR #9883 / #10293) |
可以看到,这个类型包的版本演进与整个 SDK 的架构转型(模块化)、工程基建(TypeScript 版本、依赖管理)以及模拟器生态(emulator、mock token)高度同步。
二、0.3.13:Observer 回调全部可省略
0.3.13 的变更(PR #3224)是"为所有使用 Observer 的 API 更新 TypeScript 类型,允许省略回调"。这对应 index.d.ts 中的StorageObserver<T>:
export interface StorageObserver<T> { next?: NextFn<T> | null; error?: (error: FirebaseStorageError) => void | null; complete?: CompleteFn | null; }三个回调全部是可选的(?),配合UploadTask.on()的签名(index.d.ts),开发者可以只监听完成、只监听进度,甚至先拿到订阅函数再延迟注册回调。这正是 Firebase Storage 上传任务"观察者模式"的典型用法:next观察进度、error处理失败、complete收尾,三者互不依赖。
三、0.4.0:useEmulator()方法加入类型契约
0.4.0(PR #4346)为 Storage 增加了模拟器支持,对应 index.d.ts 中FirebaseStorage类上的useEmulator方法:
useEmulator( host: string, port: number, options?: { mockUserToken?: EmulatorMockTokenOptions | string; } ): void;在模块化 SDK 中,这个能力由 api.ts 导出的connectStorageEmulator(storage, host, port, options)提供(useEmulator是 compat 层对它的封装)。其底层实现位于 service.ts 的connectStorageEmulator函数:
export function connectStorageEmulator( storage: FirebaseStorageImpl, host: string, port: number, options: { mockUserToken?: EmulatorMockTokenOptions | string } = {} ): void { storage.host = `${host}:${port}`; const useSsl = isCloudWorkstation(host); if (useSsl) { void pingServer(`https://${storage.host}/b`).catch(() => {}); } storage._isUsingEmulator = true; storage._protocol = useSsl ? 'https' : 'http'; const { mockUserToken } = options; if (mockUserToken) { storage._overrideAuthToken = typeof mockUserToken === 'string' ? mockUserToken : createMockUserToken(mockUserToken, storage.app.options.projectId); } }几个值得注意的实现细节:
- 主机拼接:把默认主机
firebasestorage.googleapis.com(constants.ts)替换为host:port,所有后续请求都指向模拟器; - 协议自适应:普通 localhost 走
http;若是 Cloud Workstations 环境(isCloudWorkstation)则强制https并附带一个 cookie 预热请求,这是针对 Firebase Studio 等环境的特殊处理; - 令牌注入:传入
mockUserToken时写入_overrideAuthToken,后续请求头Authorization: Firebase <token>将使用该令牌; - 自动连接:
getStorage()内部还会调用getDefaultEmulatorHostnameAndPort('storage'),一旦检测到环境变量配置的模拟器地址就自动连接(api.ts)。
单元测试 service.test.ts 验证了这些行为:设置localhost:1234后host变为localhost:1234、协议为http、请求 URL 匹配http://localhost:1234/...;而传入test.cloudworkstations.dev时协议变为https。
四、0.5.0:mockUserToken与 JWT 格式修复
0.5.0(PR #5282)实现了 Storage 的mockUserToken并修复了 JWT 格式问题。mockUserToken的用途是在单元测试中模拟一个已认证用户,从而测试 Security Rules。它接受两种形式:
- 字符串形式:直接作为令牌使用(
typeof mockUserToken === 'string'分支); - 对象形式:交给
createMockUserToken(mockUserToken, projectId)生成一个无签名的 JWT(alg: "none")。
对象形式的具体构造逻辑在 emulator.ts:使用sub或user_id字段作为用户 ID,默认填充iss、aud、exp(iat + 3600)、firebase.sign_in_provider: 'custom'等字段,再以 base64url 编码的 header/payload 拼接空签名。同时该实现会拒绝已废弃的uid字段并抛出明确提示——这也是 CHANGELOG 中所说"修复 JWT 格式问题"的一部分。类型定义EmulatorMockTokenOptions为({ user_id: string } | { sub: string }) & Partial<FirebaseIdToken>(emulator.ts),并明确uid?: never以在编译期拦截误用。
测试用例验证了两种形式的效果:字符串令牌直接出现在Authorization: Firebase <token>请求头中;对象形式(如{ sub: 'alice' })生成的令牌以eyJhbGciOiJub25lIiwidHlwZSI6IkpXVCJ9.开头,正是{ "alg": "none", "type": "JWT" }的 base64url 编码(service.test.ts)。
五、0.6.0:模块化 SDK 与类型包的分工
0.6.0(PR #5345,修复 #5015)标志着 SDK 全面模块化。在此之前@firebase/storage-types承载的是兼容层(compat)API 的类型;模块化之后,新一代的公开类型定义迁移到了主包 public-types.ts(包含StorageReference、ListOptions、UploadTask、StorageObserver、FullMetadata等),而@firebase/storage-types继续为 compat 层提供兼容类型契约,并在 index.d.ts 中通过declare module '@firebase/component'将storage-compat服务注册进组件依赖注入映射。
这一阶段还体现出一个细节:虽然主包已模块化,useEmulator等旧 API 名称仍保留在类型包中,保证从旧版迁移到新版(例如把firebase.storage().useEmulator(...)换成connectStorageEmulator(storage, ...))时有类型可循、迁移成本可控。
六、0.8.0:StorageError的 instanceof 判断修复
0.8.0(PR #6974,修复 #6944)修复了"用户无法用instanceof StorageError判断错误实例"的问题。这是 JavaScript 继承机制的一个经典陷阱:StorageError继承自FirebaseError,当 TypeScript 编译目标把类编译成 ES5 风格的构造函数时,instanceof可能失效。
修复方法直接体现在 error.ts 的构造函数中:
constructor( code: StorageErrorCode, message: string, private status_ = 0 ) { super( prependCode(code), `Firebase Storage: ${message} (${prependCode(code)})` ); this._baseMessage = this.message; // Without this, `instanceof StorageError`, in tests for example, // returns false. Object.setPrototypeOf(this, StorageError.prototype); }Object.setPrototypeOf(this, StorageError.prototype)显式修正原型链,使err instanceof StorageError恢复正确结果。同时,StorageError对外暴露了:
code:带storage/前缀的错误码(prependCode(code)生成,见 error.ts);customData.serverResponse:服务端返回的原始响应文本;status:对应的 HTTP 状态码;_codeEquals(code):忽略前缀地比较错误码。
类型包侧则对应 index.d.ts 的StorageErrorCode枚举与FirebaseStorageError接口。StorageErrorCode枚举共 24 个错误码,覆盖了共享错误(unknown、object-not-found、bucket-not-found、quota-exceeded、unauthorized等)与 JS 特有错误(invalid-url、invalid-format、no-default-bucket、cannot-slice-blob、server-file-wrong-size、unsupported-environment等),这些枚举值也在 error.ts 中一一对应实现。
七、工程基建类变更:TypeScript 版本与依赖管理
CHANGELOG 后半段的多次 Patch 变更集中在工程基建上:
- 0.6.1 / 0.7.0(PR #6682 / #6799):TypeScript 升级至 4.7.4;
- 0.8.1(PR #8079):统一所有包
package.json的repository.url为 NPM 偏好的格式; - 0.8.2(PR #8237):全包 bump 以配合 staging 发布流程;
- 0.8.3(PR #8604):TypeScript 升级至 5.5.4,当前 package.json 中
devDependencies.typescript即为5.5.4; - 0.8.4 / 0.8.5(PR #9883 / #10293):更新依赖与顶层 devDependencies。
由于类型包自身的"测试"就是tsc类型检查(package.json 中test: tsc),TypeScript 版本升级直接影响类型声明的正确性与兼容性——这也解释了为什么类型包会如此频繁地跟随 TS 主版本升级。对于开发者而言,这些变更的意义在于:使用新版 TypeScript 编译自己的项目时,@firebase/storage-types的类型定义能够保持兼容,不会因编译目标差异产生类型错误。
八、类型契约速览:这份.d.ts到底定义了哪些 API
把 index.d.ts 当作一份"接口地图",Storage 类型包的核心类型可以归纳如下:
| 类型 | 关键字段 / 方法 | 用途 |
|---|---|---|
FirebaseStorage | ref()、refFromURL()、setMaxOperationRetryTime()、setMaxUploadRetryTime()、useEmulator() | Storage 服务实例 |
Reference | child()、put()、putString()、getDownloadURL()、getMetadata()、updateMetadata()、delete()、list()、listAll() | 对象/路径引用 |
UploadTask | on()、pause()、resume()、cancel()、then()、catch()、snapshot | 可观察的上传任务 |
UploadTaskSnapshot | bytesTransferred、totalBytes、state、ref、metadata | 上传进度快照 |
SettableMetadata | cacheControl、contentType、contentLanguage、customMetadata等 | 可写元数据 |
UploadMetadata | 继承SettableMetadata,追加md5Hash | 上传元数据 |
FullMetadata | 继承UploadMetadata,追加bucket、generation、size、downloadTokens等 | 完整元数据 |
ListOptions/ListResult | maxResults、pageToken/prefixes、items、nextPageToken | 目录列举 |
StorageErrorCode | 24 个storage/*错误码 | 错误分类 |
值得注意的默认值与上限:ListOptions.maxResults的默认和最大值都是 1000(见 public-types.ts 的文档注释);setMaxOperationRetryTime与setMaxUploadRetryTime的默认值分别是 2 分钟与 10 分钟(constants.ts)。理解这些类型契约,无论做二次封装、编写类型安全的业务代码,还是排查类型报错,都有直接的帮助。
结语
@firebase/storage-types的 CHANGELOG 看起来只是几十行版本记录,但每一条都对应着真实的功能演进:Observer 类型从严格到宽松的 API 设计、模拟器接入从无到有、mockUserToken从实现到 JWT 格式修正、StorageError原型链修复,以及 TypeScript 与依赖基建的持续跟进。透过类型包的视角,可以清晰地看到 Firebase JS SDK 如何在保持 API 兼容的同时持续打磨类型安全与开发体验。若想深入探索,推荐继续阅读 public-types.ts(模块化公开类型)、service.ts(服务与模拟器实现)和 error.ts(错误模型),并结合 service.test.ts 中的单元测试理解各项行为的验证方式。
- 开发工具
- 后端
【免费下载链接】firebase-js-sdk
Firebase Javascript SDK
相关推荐
Wand-Enhancer 完全指南:三分钟本地补丁,免费解锁 Wand 订阅功能
Wand Enhancer 完全指南:三分钟本地补丁,免费解锁 Wand 订阅功能 Wand(原 WeMod)免费版每天只给两小时额度,倒计时一归零,修改器直接
开发工具后端firebase-js-sdk @firebase/firestore 变更日志深度解读:从 0.1.0 到 4.18.0 的版本演进与关键特性追踪
firebase js sdk @firebase/firestore 变更日志深度解读:从 0.1.0 到 4.18.0 的版本演进与关键特性追踪 @fire
开发工具后端Cloud Storage for Firebase JS SDK:从 @firebase/storage 版本演进看核心能力与实现原理
Cloud Storage for Firebase JS SDK:从 @firebase/storage 版本演进看核心能力与实现原理 本文以 firebas
开发工具后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考