Hirusha Randunu
Hirusha Randunu

Reputation: 35

how to send multiple files into fire base storage and save their URL in real time database in one record

i want to send multiple file to Fire-base storage and meantime it has to save real-time database as a one record using java-script ex: file1 : urlonfirstfile file2 : urlonsecondfile

            for (var i = 0; i < file.length; i++) {

                var task = ref.child(file.name).put(file, metadata);
                task
                    .then(snapshot => snapshot.ref.getDownloadURL())
                    .then((url) => {
                        console.log(url);
                        userDetails.push({

                            email : email,
                            title1: tit,
                            detail1: dit,
                            file:file[i].name

                        });

                    });
            }

Upvotes: 0

Views: 328

Answers (1)

samthecodingman
samthecodingman

Reputation: 26171

Your question is kinda vague on what information you want to store. So I've made some assumptions to come up with the below code:

  • The files are to be uploaded to an area of Firebase Storage specific to the logged in user. (e.g. "userFiles/CURRENT_USER/...")
  • The information about the uploaded files are kept under the user's own data. (e.g. "users/CURRENT_USER/uploads/..."
  • The title and detail properties change for each file. Where these properties come from is unclear, so I'm just going to assume they are passed in through the object metadata.

The code below should be enough to get you started on figuring out your own solution.

// the array of File objects to upload
const fileObjArray = [ ... ]

// the metadata to store with each file
const metadata = { ... }

// the current user's ID
const currentUserId = firebase.auth().currentUser.uid;

// Where to save information about the uploads
const databaseRef = firebase.database().ref("user").child(currentUserId).child('uploads');

// Create an ID for this set of uploaded files
const uploadId = storageRef.push().key;

// Save files to storage in a subfolder of the user's files corresponding to the uploadId
const storageRef = firebase.storage().ref("userFiles").child(currentUserId).child(uploadId);

// Upload each file in fileObjArray, then fetch their download URLs and then return an object containing information about the uploaded file
var uploadPromiseArray = fileObjArray.map((fileObj) => {
    var uploadTask = storageRef.child(fileObj.name).put(fileObj, metadata)

    return uploadTask.then(uploadSnapshot => {
            // file uploaded successfully. Fetch url for the file and return it along with the UploadTaskSnapshot
            return uploadSnapshot.ref.getDownloadURL().then((url) => {
                    return {
                        downloadUrl: url,
                        snapshot: uploadSnapshot
                    };
                });
        });
});

// uploadPromiseArray is an array of Promises that resolve as objects with the properties "downloadUrl" and "snapshot"
Promise.all(uploadPromiseArray)
    .then((uploadResultArray) => {
        var batchUploadData = {
            timestamp: firebase.database.ServerValue.TIMESTAMP, // use the server's time
            files: [],
            ... // other upload metadata such as reason, expiry, permissions, etc.
        }

        batchUploadData.files = uploadResultArray.map((uploadResult) => {
            // rearrange the file's snapshot data and downloadUrl for storing in the database
            return {
                file: uploadResult.snapshot.name,
                url: uploadResult.url,
                title: uploadResult.snapshot.metadata.customMetadata.title,
                detail: uploadResult.snapshot.metadata.customMetadata.detail
            };
        });

        // commit the data about this upload to the database.
        return databaseRef.child(uploadId).set(batchUploadData);
    })
    .then((dataSnapshot) => {
        // the upload completed and information about the upload was saved to the database successfully

        // TODO: do something
    }, (err) => {
        // some error occured
        // - a file upload failed/was cancelled
        // - the database write failed
        // - permission error from Storage or Realtime Database

        // TODO: handle error
    });

// Warning: this line will be reached before the above code has finished executing

This is what it looks like on the database:

"users": {
    "someUserId-78sda9823": {
        "email": "[email protected]",
        "name": "mr-example",
        "username": "mrexemplary",
        "uploads": {
            "niase89f73oui2kqwnas98azsa": {
                "timestamp": 1554890267823,
                "files": {
                    "1": {
                        "file": "somefile.pdf",
                        "url": "https://firebasestorage.googleapis.com/v0/b/bucket/o/userFiles%2FsomeUserId-78sda9823%2Fsomefile.pdf",
                        "title": "Some File",
                        "detail": "Contains a report about some stuff"
                    },
                    "2": {
                        "file": "screenshot.png",
                        "url": "https://firebasestorage.googleapis.com/v0/b/bucket/o/userFiles%2FsomeUserId-78sda9823%2Fscreenshot.png",
                        "title": "Screenshot of problem",
                        "detail": "Contains an image that shows some stuff"
                    },
                    ...
                }
            },
            ...
        },
        ...
    },
    ...
}

Note 1: This code is not yet complete. It is missing error handling for things like permission errors and incomplete file uploads. This is a problem for you to solve.

Note 2: Regarding incomplete file uploads, if any file fails to upload or get it's download URL successfully, the database will not be written to. One possible way to aid with this is to add a catch to uploadTask that returns null on error and then in the uploadResultArray.map(...) step skip any uploadResult variables that are null or write to the database that it failed for that particular file.

Note 3: Because Firebase Storage and the Realtime Database both use snapshots, try to keep them called uploadSnapshot/fileSnapshot and dataSnapshot respectively when using both in your code to minimise confusion. Similarly, name your references somethingStorageRef/somethingSRef and somethingDatabaseRef/somethingDBRef.

Upvotes: 1

Related Questions