如何将站点地图爬取的链接逐个存入Firebase集合?解决数据格式报错
解决Firebase保存站点地图链接的报错问题
报错原因
你遇到的Function DocumentReference.set() called with invalid data. Data must be an object错误,根源有两个:
- Firebase的
doc().set()方法要求传入对象类型的数据,但你直接传了数组urls - 当前代码试图把所有链接存在一个名为
test的文档里,不符合“每个链接作为独立文档保存”的需求
修正后的保存函数
要实现每个链接对应集合里的独立文档,同时满足Firebase的数据格式要求,你可以用以下两种方式修改saveAllCrawl函数:
方式1:批量操作(适合大量链接)
用Firebase的批量写入API,减少网络请求次数:
const saveAllCrawl = async () => { const batch = db.batch(); urls.forEach(url => { // 自动生成唯一文档ID const docRef = db.collection('urls').doc(); // 传入对象格式的数据,把链接存在url字段中 batch.set(docRef, { url: url }); }); await batch.commit(); console.log('所有链接已成功保存到Firebase'); }
方式2:Promise.all并行写入
如果链接数量不多,也可以用Promise.all并行处理:
const saveAllCrawl = async () => { await Promise.all( urls.map(url => { // add()方法会自动生成文档ID,传入对象数据 return db.collection('urls').add({ url: url }); }) ); console.log('所有链接保存完成'); }
额外优化(可选)
如果要避免重复保存相同链接,可以给每个链接生成唯一的文档ID(比如用链接的哈希值),再用set()的merge参数防止覆盖:
const saveAllCrawl = async () => { const batch = db.batch(); urls.forEach(url => { // 前端环境用btoa生成简易唯一ID(注意处理特殊字符) const docId = btoa(url).replace(/[+/=]/g, ''); const docRef = db.collection('urls').doc(docId); // merge: true 表示如果文档已存在,只更新字段,不覆盖 batch.set(docRef, { url: url }, { merge: true }); }); await batch.commit(); console.log('所有链接已保存(自动去重)'); }
内容的提问来源于stack exchange,提问作者Tom Galland
相关产品推荐
相关产品推荐

