Search code examples
firebasecachinggoogle-cloud-functionscdnfirebase-hosting

Firebase hosting with cloud functions - how to purge/refresh CDN cache?


I'm following the instructions from this video and so far things are working perfectly right up to the point where I need to purge the CDN of old HTML:

https://www.youtube.com/watch?v=7_2CJs_VZk4

So far I've created a static HTML page using Firebase Cloud Functions, and it is stored on Firebase Cloud Storage. Whenever data from my Firebase Database is updated, a new and updated static HTML page is rendered and is saved to the Cloud Storage.

Firebase Hosting serves that static HTML page, and it is stored on the CDN. As per the above video, I've set a long refresh time for the CDN because I only want it to update when I make a change to the data in Firebase Database (no refreshing the CDN if no change has been made)

For this to work, when the page is updated, the old HTML page stored on the CDN must be purged and replaced with the new HTML page.

The video at time 33:19 suggests the following code:

const purgeUrl = `${ORIGIN}/${path}`;
await request(purgeUrl, { method: "PURGE" });

Unfortunately it doesn't seem to work. I can see that the page has updated on Cloud Storage, but when I refresh the URL the new HTML page is not displayed. The only way I can show the new HTML is by re-deploying the firebase code again (terminal - firebase deploy).

Here is my code (in node.js):

const ORIGIN = "examplesite-30ccf.firebaseapp.com/";

function getFacts(){
  return database.ref('/web app/test').once('value').then(snap =>snap.val());
}

exports.updateHomePage = functions.database.ref('/web app/test')
.onWrite((snap, context) => {

  return getFacts()
  .then(result1 => {
    console.log("result1", result1);
      return bucket
      .file('public_html/index.html')
      .save(HomePage(result1), {
        gzip: true,
        metadata: {
          contentType: "text/html; charset=utf-8",
          cacheControl: "max-age=300, s-maxage=31536000" // indef CDN cache since we purge manually
        }
      }); 
  }).then(doNotUse => {

    const purgeUrl = `${ORIGIN}`;
    console.log("purged URL", purgeUrl);
    return request(purgeUrl, { method: "PURGE" });
}).catch(error => {
      // Handle errors of asyncFunc1() and asyncFunc2()
  });

});`

There is no crash or exceptions in the Firebase Functions logs. Any help is much appreciated. Thanks


Solution

  • I inadvertently found the answer while trying to fix another issue.

    You need to be on a paid Firebase plan to make external API calls: https://firebase.google.com/pricing/

    So the PURGE method does work so long as you have upgraded you plan. Here is the code that allows you to purge the CDN (Node.js in Typescript):

    import * as request from "request-promise";
    
    const purgeUrl = `examplesite.com`;
    await request(purgeUrl, { method: "PURGE" });