我们使用带有 Firebase HTTP API 的 HTTP 流来克服保存、本地修改和上传巨大(超过 256mb)JSON 文件的麻烦。
我们构建了一个函数来从一个项目的数据库到另一个项目的数据库的 HTTP 管道数据流:
async function copyFirebasePath(path, from, to) {
// getAccessToken from https://firebase.google.com/docs/database/rest/auth
const fromAccessToken = await getAccessToken(from.key)
const toAccessToken = await getAccessToken(to.key)
return new Promise((resolve, reject) => {
let toRequest
// create write request, but don’t start writing to it
// we’ll pipe the read request as the data to write
try {
toRequest = https.request(
`${to.databaseUrl}/${path}.json?print=silent`,
{
method: 'PUT',
headers: {
Authorization: `Bearer ${toAccessToken}`
}
},
(/* res */) => {
resolve()
}
)
} catch (writeError) {
reject(writeError)
}
try {
https
.request(
`${from.databaseUrl}/${path}.json`,
{
method: 'GET',
headers: {
Authorization: `Bearer ${fromAccessToken}`
}
},
res => {
res.pipe(toRequest)
res.on('end', () => {
toRequest.end()
})
}
)
.end()
} catch (readError) {
reject(readError)
}
})
}
我们像这样使用它:
// get Object.keys from remote db
const shallowDB = await request({
method: 'get',
// note ?shallow=true here – prevents loading the whole db!
url: `${from.databaseUrl}/.json?shallow=true`,
options: {
headers: {
Authorization: `Bearer ${fromAccessToken}`
}
}
})
const dbKeys = Object.keys(shallowDB)
const keysToOmit = ['foo', 'bar', 'baz']
try {
await Promise.all(
dbKeys
.filter(dbKey => !keysToOmit.includes(dbKey))
.map(key => copyFirebasePath(key, from, to))
)
} catch (copyError) {
console.log(copyError)
throw new Error(copyError)
}