How to move files with firebase storage?
Asked Answered
J

7

29

Is there a way to move files with firebase.storage()?

Example: user1/public/image.jpg to user1/private/image.jpg

Junette answered 26/7, 2016 at 23:41 Comment(1)
See "Renaming, copying, and moving objects" here:cloud.google.com/storage/docs/renaming-copying-moving-objectsDisaccharide
B
14

There is no such way to move to other location, rather you can download and then put it to other reference and deleting the previous location.

Berneicebernelle answered 27/7, 2016 at 0:53 Comment(0)
P
19

Since Firebase Storage is backed by Google Cloud Storage, you can use GCS's rewrite API (docs) or gsutil mv (docs).

Also, an example of move (docs) in GCloud Node follows:

var bucket = gcs.bucket('my-bucket');
var file = bucket.file('my-image.png');
var newLocation = 'gs://another-bucket/my-image-new.png';
file.move(newLocation, function(err, destinationFile, apiResponse) {
  // `my-bucket` no longer contains:
  // - "my-image.png"
  //
  // `another-bucket` now contains:
  // - "my-image-new.png"

  // `destinationFile` is an instance of a File object that refers to your
  // new file.
});
Phosphocreatine answered 27/7, 2016 at 4:55 Comment(2)
Is there a way to use this solution combined with the firebase's storage rules?Junette
Currently no, but in the future we may allow service accounts to be subjected to the same rules that third party authenticated users are.Phosphocreatine
B
14

There is no such way to move to other location, rather you can download and then put it to other reference and deleting the previous location.

Berneicebernelle answered 27/7, 2016 at 0:53 Comment(0)
R
11

As of March 29, 2022 it is possible to call the "move" function directly in this way:

import * as functions from "firebase-functions";
import {getStorage} from "firebase-admin/storage";

export const triggerStorage = functions
  .storage
  .object()
  .onFinalize(async (object) => {
    const bucket = getStorage().bucket(object.bucket);
    const destPath = "user1/private/image.jpg";
    await bucket.file(object.name).move(destPath);
  });
Repudiation answered 29/3, 2022 at 8:51 Comment(0)
B
3

I wrote a JavaScript function that accomplishes this using only the firebase storage API.

Happy Coding!

/**
 * Moves a file in firebase storage from its current location to the destination
 * returns the status object for the moved file.
 * @param {String} currentPath The path to the existing file from storage root
 * @param {String} destinationPath The desired pathe for the existing file after storage
 */
function moveFirebaseFile(currentPath, destinationPath) {
    let oldRef = storage.ref().child(currentPath)

    oldRef.getDownloadURL().then(url => {
        fetch(url).then(htmlReturn => {
            let fileArray = new Uint8Array()
            const reader = htmlReturn.body.getReader()

            //get the reader that reads the readable stream of data
            reader
                .read()
                .then(function appendStreamChunk({ done, value }) {
                    //If the reader doesn't return "done = true" append the chunk that was returned to us
                    // rinse and repeat until it is done.
                    if (value) {
                        fileArray = mergeTypedArrays(fileArray, value)
                    }
                    if (done) {
                        console.log(fileArray)
                        return fileArray
                    } else {
                        // "Readout not complete, reading next chunk"
                        return reader.read().then(appendStreamChunk)
                    }
                })
                .then(file => {
                    //Write the file to the new storage place
                    let status = storage
                        .ref()
                        .child(destinationPath)
                        .put(file)
                    //Remove the old reference
                    oldRef.delete()

                    return status
                })
        })
    })
}

Blacking answered 3/1, 2020 at 23:22 Comment(3)
@newswiftcoder yes, it is. it uses ES6 syntax (arrow functions, fetch, object destructuring, etc.)Institutionalize
So it is like downloading and uploading. Same idea. I wished there is some API that does that without downloading the files (either locally or via cloud functions).Grotto
mergeTypedArrays isn't found. Is this defined in a package somewhere?Emoryemote
H
0

One thing you might stumble upon when using the other answers - when downloading the file it will have the file name of the old, copied file.

To fix that issue you need to change the contentDisposition metadata of the file.

let metadata = {
        // Here predefined key/value
        contentDisposition: "inline; filename=yourfilename.txt",

        metadata: {
          // Not here! custom key/value
        },
      };

To see the full predefined metadata properties: https://firebase.google.com/docs/storage/web/file-metadata

Hughhughes answered 6/10, 2023 at 17:54 Comment(0)
U
0

In Google Cloud Console > Cloud Storage > Bucket > yourapp.appspot.com > Transfer Data IN/OUT (Options: Choose a source > Filter by Prefix > Exclude/Include file/folder to be moved, for example if you want to move all the files from the bucket in the folder Users, you want to exclude the folder "Users/")

You can also opt in for the data to be deleted after move in Choose Settings

Click Create and its done, it will take a few minutes if you have alot of files

Undersexed answered 18/3, 2024 at 9:44 Comment(0)
C
0
    await bucket.file(filePath).move();

The move method does nothing but simply copy and delete. The error message will indicate what operation has failed.

ref: doc

Carvey answered 23/6, 2024 at 7:30 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.