I´d like to dynamically generate a sitemap.xml containing all static and dynamic user links (through uids from Firestore) with Cloud Functions when a user or a crawler requests https://www.example.com/sitemap.xml. I already managed to implement a working version using sitemap.js (https://github.com/ekalinin/sitemap.js#generate-a-one-time-sitemap-from-a-list-of-urls) and Firebase Hosting rewrites. However, my current solution (see below) generates one large sitemap.xml and only works for up to 50000 links which is not scalable.
Current solution:
Hosting rewrite in firebase.json:
"hosting": [
...
"rewrites": [
{
"source": "/sitemap.xml",
"function": "generate_sitemap"
},
]
}
],
Function in index.ts
export const generateSitemap = functions.region('us-central1').https.onRequest((req, res) => {
const afStore = admin.firestore();
const promiseArray: Promise<any>[] = [];
const stream = new SitemapStream({ hostname: 'https://www.example.com' });
const fixedLinks: any[] = [
{ url: `/start/`, changefreq: 'hourly', priority: 1 },
{ url: `/help/`, changefreq: 'weekly', priority: 1 }
];
const userLinks: any[] = [];
promiseArray.push(afStore.collection('users').where('active', '==', true).get().then(querySnapshot => {
querySnapshot.forEach(doc => {
if (doc.exists) {
userLinks.push({ url: `/user/${doc.id}`, changefreq: 'daily', priority: 1 });
}
});
}));
return Promise.all(promiseArray).then(() => {
const array = fixedLinks.concat(userLinks);
return streamToPromise(Readable.from(array).pipe(stream)).then((data: any) => {
res.set('Content-Type', 'text/xml');
res.status(200).send(data.toString());
return;
});
});
});
Since, this scales only to about 50000 links, I´d like to do something like https://github.com/ekalinin/sitemap.js#create-sitemap-and-index-files-from-one-large-list. But it seems like I´d need to actually create and temporarily store .xml files somehow.
Does anyone have experience with this issue?