从Firebase Firestore迁移至Supabase
将您的Firebase Firestore数据库迁移至Supabase Postgres数据库
Supabase 提供了多种工具用于将数据从 Firebase Firestore 数据库迁移到 Supabase Postgres 数据库。该过程会将整个 Firestore collection
的内容复制到单个 Postgres table
中。
Firestore collection
会被"扁平化"处理,并转换为包含以下基本列类型的表:text
、numeric
、boolean
或 jsonb
。如果您的数据结构更复杂,可以在将 json
文件导入 Supabase 之前,编写程序将新创建的 json
文件拆分为多个相关联的表。
设置迁移工具
-
克隆
firebase-to-supabase
仓库:1git clone https://github.com/supabase-community/firebase-to-supabase.git -
在
/firestore
目录中,创建一个名为supabase-service.json
的文件,内容如下:1234567{ "host": "database.server.com", "password": "secretpassword", "user": "postgres", "database": "postgres", "port": 5432} -
在项目仪表板中,点击连接
-
在会话池下,点击连接字符串下方的查看参数。将
Host
和User
字段替换为显示的值。 -
在
supabase-service.json
文件的password
字段中输入创建 Supabase 项目时使用的密码。
生成 Firebase 私钥
- 登录 Firebase 控制台并打开您的项目
- 在侧边栏中点击项目概览旁边的齿轮图标,选择项目设置
- 点击服务账户,选择Firebase Admin SDK
- 点击生成新的私钥
- 将下载的文件重命名为
firebase-service.json
命令行选项
列出所有 Firestore 集合
node collections.js
将 Firestore 集合转储为 JSON 文件
node firestore2json.js <collectionName> [<batchSize>] [<limit>]
batchSize
(可选) 默认为 1000- 输出文件名为
<collectionName>.json
limit
(可选) 默认为 0 (无限制)
使用钩子自定义 JSON 文件
您可以使用自定义钩子来定制 JSON 文件的生成方式。常见的用途包括"扁平化"JSON 文件,或将嵌套数据拆分为独立的关联数据库表。例如,您可以将如下所示的 Firestore 文档:
1[{ "user": "mark", "score": 100, "items": ["hammer", "nail", "glue"] }]
拆分为两个文件(一个用户表和一个物品表):
1[{ "user": "mark", "score": 100 }]
12345[ { "user": "mark", "item": "hammer" }, { "user": "mark", "item": "nail" }, { "user": "mark", "item": "glue" }]
将 JSON 文件导入 Supabase (Postgres)
node json2supabase.js <path_to_json_file> [<primary_key_strategy>] [<primary_key_name>]
<path_to_json_file>
上一步创建的文件的完整路径(将 Firestore 集合转储为 JSON 文件
),例如./my_collection.json
[<primary_key_strategy>]
(可选) 可以是以下之一:none
(默认) 不向表添加主键。smallserial
使用(id SMALLSERIAL PRIMARY KEY)
创建键(自动递增的 2 字节整数)。serial
使用(id SERIAL PRIMARY KEY)
创建键(自动递增的 4 字节整数)。bigserial
使用(id BIGSERIAL PRIMARY KEY)
创建键(自动递增的 8 字节整数)。uuid
使用(id UUID PRIMARY KEY DEFAULT gen_random_uuid())
创建键(随机生成的 UUID)。firestore_id
使用(id TEXT PRIMARY KEY)
创建键(使用现有的firestore_id
随机文本作为键)。
[<primary_key_name>]
(可选) 主键名称。默认为 "id"。
自定义钩子
钩子用于自定义将 Firestore 文档集合导出为 JSON 的过程。可用于:
- 自定义或修改键
- 计算数据
- 将嵌套文档扁平化为相关的 SQL 表
编写自定义钩子
为集合创建 .js
文件
如果您的 Firestore 集合名为 users
,在当前文件夹中创建一个名为 users.js
的文件。
构建您的 .js
文件
钩子文件的基本格式如下:
1234module.exports = (collectionName, doc, recordCounters, writeRecord) => { // 在此处修改文档 return doc}
参数
collectionName
: 正在处理的集合名称。doc
: 当前正在处理的文档(JSON对象)。recordCounters
: 内部对象,用于跟踪每个集合中已处理的记录数量。writeRecord
: 该函数自动处理将数据写入其他JSON文件的过程(适用于将文档"扁平化"到单独的JSON文件中,以便写入不同的数据库表)。writeRecord
接收以下参数:name
: 要写入的JSON文件名。doc
: 要写入文件的文档。recordCounters
: 传递给此钩子的同一个recordCounters
对象(仅作传递)。
示例
为集合添加新的(唯一)数字键
1234module.exports = (collectionName, doc, recordCounters, writeRecord) => { doc.unique_key = recordCounter[collectionName] + 1 return doc}
添加从Firestore转储此记录时的时间戳
1234module.exports = (collectionName, doc, recordCounters, writeRecord) => { doc.dump_time = new Date().toISOString() return doc}
将 JSON 扁平化为独立文件
将 users
集合扁平化为独立文件:
1234567891011121314[ { "uid": "abc123", "name": "mark", "score": 100, "weapons": ["toothpick", "needle", "rock"] }, { "uid": "xyz789", "name": "chuck", "score": 9999999, "weapons": ["hand", "foot", "head"] }]
users.js
钩子文件:
1234567891011module.exports = (collectionName, doc, recordCounters, writeRecord) => { for (let i = 0; i < doc.weapons.length; i++) { const weapon = { uid: doc.uid, weapon: doc.weapons[i], } writeRecord('weapons', weapon, recordCounters) } delete doc.weapons // 已移至独立文件 return doc}
结果生成两个独立的 JSON 文件:
1234[ { "uid": "abc123", "name": "mark", "score": 100 }, { "uid": "xyz789", "name": "chuck", "score": 9999999 }]
12345678[ { "uid": "abc123", "weapon": "toothpick" }, { "uid": "abc123", "weapon": "needle" }, { "uid": "abc123", "weapon": "rock" }, { "uid": "xyz789", "weapon": "hand" }, { "uid": "xyz789", "weapon": "foot" }, { "uid": "xyz789", "weapon": "head" }]
相关资源
企业服务
如需获取项目迁移的更多帮助,请联系我们。