Ionică Bizău
Ionică Bizău

Reputation: 113455

The images from Google Cloud bucket are not immediately updated

When updating an image in Google Cloud bucket, even if the image update is successful, the url serves the old version for a while (few minutes, e.g. 5 min or so).

The link we are using looks like:

https://storage.googleapis.com/<bucket-name>/path/to/images/1.jpg

The relevant part of the code which updates the image is:

var storageFile = bucket.file(imageToUpdatePath);
var storageFileStream = storageFile.createWriteStream({
  metadata: {
    contentType: req.file.mimetype
  }
});

storageFileStream.on('error', function(err) {
   ...
});

storageFileStream.on('finish', function() {
  // cloudFile.makePublic after the upload has finished, because otherwise the file is only accessible to the owner:
  storageFile.makePublic(function(err, data) {
    //if(err)
    //console.log(err);
    if (err) {
      return res.render("error", {
        err: err
      });
    }
    ...
  });
});
fs.createReadStream(filePath).pipe(storageFileStream);

It looks like a caching issue on the Google Cloud side. How to solve it? How to get the updated image at the requested url, after being updated?

In the Google Cloud admin, the new image does appear correctly.

Upvotes: 2

Views: 1684

Answers (2)

Abhishek K
Abhishek K

Reputation: 51

Reference: https://cloud.google.com/storage/docs/viewing-editing-metadata#code-samples_1

    1. await bucket
                .file(filePath)
                .delete({ ignoreNotFound: true });

    // Deleting file with a name.
    
    const blob = bucket.file(filePath);
    
   2. await blob.save(fil?.buffer);

    //Saving File with the same name 
    
   3. const [metadata] = await storage
              .bucket(bucketName)
              .file(filePath)
              .getMetadata();
    
    newDocObj.location = metadata.mediaLink;

I have used metadata.mediaLink to get the 
latest download link of the image from Google Bucket Storage.

Upvotes: 0

Travis Hobrla
Travis Hobrla

Reputation: 5509

By default, public objects get cached for up to 60 minutes - see Cache Control and Consistency. To fix this, you should set the cache-control property of the object to private when you create/upload the object. In your code above, this would go in the metadata block, like so:

var storageFileStream = storageFile.createWriteStream({
  metadata: {
    contentType: req.file.mimetype,
    cacheControl: 'private'
  }
});

Upvotes: 6

Related Questions