Firebase hosting file upload via REST with Apps Script

Viewed 35

I want to upload a file to Firebase hosting file upload via REST with Apps Script. Been trying to find a solution for days to no avail :( would highly appreciate any recommendations.

I'm following the official documentation here: https://firebase.google.com/docs/reference/hosting/rest/v1beta1/sites.versions/populateFiles

And I can successfully get the upload URL using this code:

function getUploadURL() {
  const YOUR_PROJECT_ID = 'sites/url-shortener-e42ec/versions/dd393a80797d713d';

  let postUrl = 'https://firebasehosting.googleapis.com/v1beta1/YOUR_PROJECT_ID:populateFiles';
  postUrl = postUrl.replace('YOUR_PROJECT_ID', YOUR_PROJECT_ID);

  const options = {
    method: 'post',
    headers: { 
      Authorization: `Bearer ${ScriptApp.getOAuthToken()}`,
    },
    muteHttpExceptions: true
  };

  const response = UrlFetchApp.fetch(postUrl, options);
  Logger.log(response);
}

which returns the following:

{
  "uploadUrl": "https://upload-firebasehosting.googleapis.com/upload/sites/url-shortener-e42ec/versions/dd393a80797d713d/files"
}

And this is where I get kinda lost because I'm not quite sure on what to do next. The documentation says:

map (key: string, value: string)

A set of file paths to the hashes corresponding to assets that should be added to the version.

A file path to an empty hash will remove the path from the version.

Calculate a hash by Gzipping the file then taking the SHA256 hash of the newly compressed file.

But if I add a payload with a file hash to the call like so:

{
  "files": {
    "/teste": "3f0749957a1c4d91ed18b8e9df122709974e4e9c94c57f9245794c21dd76d4bd"
  }
}

...then I get the error:

{
  "error": {
    "code": 400,
    "message": "Precondition check failed.",
    "status": "FAILED_PRECONDITION"
  }
}

PART 2 : The next issue I found is, now that I have the upload URL, I will need to actually upload the file, and according to their documentation I should:

Perform a multipart POST of the Gzipped file contents to the URL using a forward slash and the hash of the file appended to the end.

which I tried with the following apps script code:

function convert(hash) {
  return hash.map(byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('');
}

function postFile() {
  var files = DriveApp.getFilesByName('abc.txt');
  let gzip;
  let hash;

  if (files.hasNext()) {
    var file = files.next();
    gzip = Utilities.gzip(file.getBlob());   
    hash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, gzip.getBytes());
  }

  let postUrl = 'https://upload-firebasehosting.googleapis.com/upload/sites/url-shortener-e42ec/versions/dd393a80797d713d/files/' + convert(hash);

  /*
  var textBlob = Utilities.newBlob("abc");
  const gzip = Utilities.gzip(textBlob);
  const hash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, gzipFile.getBytes());
  */
  
  const data = {
    "files": {
      "/test.txt": convert(hash)
    }
  };
                        
  const options = {
    method: 'post',
    headers: { 
      Authorization: `Bearer ${ScriptApp.getOAuthToken()}`,
      accept: 'application/json',
      contentType: 'application/json'
    },
    muteHttpExceptions: true,
    payload: JSON.stringify(data) 
  };

  const response = UrlFetchApp.fetch(postUrl, options);
  Logger.log(response);
}

... and get the following error:

Couldn't process request (status=412): File url-shortener-e42ec/dd393a80797d713d/0b3b82379e00a1994a46452e8cfd8b2c43ee8599f169a9ee4176253f1a8de469 can't be uploaded.

Appreciate all the help I can get. Thanks in advance!

0 Answers
Related