DEV Community

Cover image for How I Created a File Sharing Website using Simple JavaScript
Varshith V Hegde
Varshith V Hegde

Posted on • Edited on

How I Created a File Sharing Website using Simple JavaScript

Any Share is a simple, lightweight, and fast file sharing service. It is written in Javascript and uses the Firebase platform.

Website I created for secure file sharing with friends and family.

You can Create your own website with this code.

Features

  • Upload files
  • Download files
  • Delete files
  • Share files
  • View files
  • Secure file sharing

Working

  • Any Share uses Firebase to store files. It uses Firebase Storage to store files and Firebase Realtime Database to store metadata of files.
  • When a file is uploaded, it is stored in Firebase Storage and a unique ID is generated for the file. This ID is used to access the file.
  • The metadata of the file is stored in Firebase Realtime Database. This metadata includes the url to the file and the unique ID of the file.
  • When a file is shared, the unique ID of the file is shared. This ID is used to access the file.
  • Receiver of the file can access the file using the unique ID of the file.
  • When the file is received by the receiver using the unique ID, the file is downloaded from Firebase Storage and displayed to the receiver.
  • Once the file is received by the receiver, the file is automatically deleted from Firebase Storage.
  • This way the file is shared securely.

How to use

  • Visit Any Share.
  • Upload a file.
  • Wait for the file to be uploaded.
  • Share the unique ID of the file with the receiver.
  • Receiver can access the file using the unique ID of the file.
  • Once the file is received by the receiver, the file is automatically deleted from Firebase Storage.

Code Review

  • Code for Firebase storage uploading
function uploadFile() {
    if(document.getElementById("file").value != ""){
    var uploadtext = document.getElementById("upload").innerHTML;
  document.getElementById("upload").innerHTML = "Uploading...";
  var file = document.getElementById("file").files[0];
  var storageRef = firebase.storage().ref("images/" + file.name);
  var uploadTask = storageRef.put(file);
  uploadTask.on('state_changed', function (snapshot) {
    var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
    console.log('Upload is ' + progress + '% done');
  }, function (error) {
    console.log(error.message);
    document.getElementById("upload").innerHTML = "Upload Failed";
  }, function () {


    uploadTask.snapshot.ref.getDownloadURL().then(function (downloadURL) {
      console.log('File available at', downloadURL);
      saveMessage(downloadURL);
    });
  });
}
else{
    var uploadtext = document.getElementById("upload").innerHTML;
    document.getElementById("upload").innerHTML = "Please select a file";
    // After 2 sec make it empty
    setTimeout(function(){
        document.getElementById("upload").innerHTML = uploadtext;
    }
    , 2000);
}
}

Enter fullscreen mode Exit fullscreen mode
  • Code for Firebase storage downloading
function showfile(){
var uniqueId= document.getElementById("unique").value;
    if(uniqueId==""){
        alert("Unique Id is empty\n Please enter a Unique Id");
        return;
    }
    var ref = firebase.database().ref("image");
    var flag = 0;
    ref.on("value", function(snapshot) {
        snapshot.forEach(function(childSnapshot) {
        var childData = childSnapshot.val();
        if (childData.number == uniqueId){

        flag = 1;
        window.open(childData.url, "_blank");
        // AFter this delete the image from the database
        ref.child(childSnapshot.key).remove();
        // Remove file from storage
        //Run this with 5sec delay
        setTimeout(function(){
        var storageRef = firebase.storage().refFromURL(childData.url);
        storageRef.delete().then(function() {
             ref.child(childSnapshot.key).remove();
        // File deleted successfully
        }).catch(function(error) {

        });
        }, 15000);


        }
        });
    }
    );
}
Enter fullscreen mode Exit fullscreen mode
  • Generated unique ID

function createUniquenumber(){
    // Create a unique 5 digit number for each image which is not in the database field number yet
    var number = Math.floor(10000 + Math.random() * 90000);
    var ref = firebase.database().ref("image");
    ref.on("value", function(snapshot) {
        snapshot.forEach(function(childSnapshot) {
        var childData = childSnapshot.val();
        if (childData.number == number){
            createUniquenumber();
        }
        });
    });
    return number;


}
Enter fullscreen mode Exit fullscreen mode
  • Code for saving metadata of file in Firebase Realtime Database
function saveMessage(downloadURL) {
    var newMessageRef = messagesRef.push();
    var unique= createUniquenumber();
    // Hidding recive file div
    var x = document.getElementById("downloadiv");
    x.style.display = "none";
    var showUnique = document.getElementById("ShowUniqueID");
    var shU=document.getElementById("showunique");
    shU.value=unique;
    showUnique.style.display = "block";

    newMessageRef.set({
        url: downloadURL,
        number: unique
    });
    document.getElementById("upload").innerHTML = "Upload Successful";
    //Make file input empty
    document.getElementById("file").value = "";

    }
Enter fullscreen mode Exit fullscreen mode

Conclusion

  • In this tutorial I have explained how I created my own File Sharing Web App.

References

Top comments (69)

Collapse
 
anurag_vishwakarma profile image
Anurag Vishwakarma

Bro I have not any coding experience, how can i deploy on other cloud platforms. (Learning DevOps)

Collapse
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

Check my posts about CI/CD anytime 😁

Collapse
 
varshithvhegde profile image
Varshith V Hegde

Sure 👍

Collapse
 
varshithvhegde profile image
Varshith V Hegde

I think Learning is part of doing project so i recommend you to go through Youtube for basics understanding and gthen go read some articles on it. But be sure not to fall in to Tutorial Hell

Collapse
 
anurag_vishwakarma profile image
Anurag Vishwakarma

Can you please share all files, codes etc.

Thread Thread
 
varshithvhegde profile image
Varshith V Hegde

Yeah sure its in my github github.com/Varshithvhegde/anyshare

Thread Thread
 
Sloan, the sloth mascot
Comment deleted
 
varshithvhegde profile image
Varshith V Hegde

Check the permission in firebase realtime allow read and write as true.

Thread Thread
 
anurag_vishwakarma profile image
Anurag Vishwakarma

Bro already did but not working.

Thread Thread
 
varshithvhegde profile image
Varshith V Hegde

And permission in storage also right??

Thread Thread
 
anurag_vishwakarma profile image
Anurag Vishwakarma

Are you talking about this ?

Thread Thread
 
varshithvhegde profile image
Varshith V Hegde

About What?

Thread Thread
 
anurag_vishwakarma profile image
Anurag Vishwakarma
Thread Thread
 
varshithvhegde profile image
Varshith V Hegde

I dont see any errors just try to check it in console error may show there

Thread Thread
 
anurag_vishwakarma profile image
Anurag Vishwakarma

I don't know what should I do ? imgur.com/a/xUglDfG I have to edit rules too ?

Thread Thread
 
varshithvhegde profile image
Varshith V Hegde

Nope everything seems correct here

Thread Thread
 
anurag_vishwakarma profile image
Anurag Vishwakarma

I tried to run code locally and removed some comments for javascript file, showing error : file not found - imgur.com/a/rF6aybH

Thread Thread
 
varshithvhegde profile image
Varshith V Hegde

Is file uploading?

Thread Thread
 
anurag_vishwakarma profile image
Anurag Vishwakarma

Yes file upload works but when I try to download file by putting code : doesn't work.

Thread Thread
 
anurag_vishwakarma profile image
Anurag Vishwakarma

bro can we chat in live ? like on messenger or WhatsApp / any other ?

Thread Thread
 
anurag_vishwakarma profile image
Anurag Vishwakarma • Edited

.

Collapse
 
faisalnarsi profile image
Faisal N.

Omg I’m in “tutorial hell” lol
Great project!

Thread Thread
 
varshithvhegde profile image
Varshith V Hegde

If you know you are in it then sure you will be out of it. Just think of any project in domain which you are good at. Do some simple project without any tutorials that's it. Yiu will be out of it in no time. That's how I came out of it. 😊

Collapse
 
anurag_vishwakarma profile image
Anurag Vishwakarma

Ok! No Problem.

Collapse
 
devarshishimpi profile image
Devarshi Shimpi

Probably deploy it to Github or maybe Vercel, you don't need much of coding experience for that. It's one click deploy to Vercel, but yes do replace with your firebase API ID's

Collapse
 
devarshishimpi profile image
Devarshi Shimpi

I think it's not actually safe using because the unique ID's r just random numbers, and entering someone else's ID's might reveal their files uploaded. Maybe fix would be generating a random string instead that too of 20+ Characters???
Nevertheless, Great article!!!

Collapse
 
varshithvhegde profile image
Varshith V Hegde • Edited

But number is 5 digit so probability is very less and this is my cloud so i don't recommend you can trust cloud. Because here i am not encrypting the file so. I would try to implemet it. By the way thanks for it. And i made it 5 digit because it would be easy to share.

Collapse
 
devarshishimpi profile image
Devarshi Shimpi

Yep I understand 5 digit are easy to share. And yes, you can always develop further add encryption. If possible find an alternative to Firebase where the pricing is more affordable. And Welcome Of course 😊😊

Thread Thread
 
emil profile image
Emil

I would suggest you have a look at pre signed urls when it comes to sharing

Thread Thread
 
varshithvhegde profile image
Varshith V Hegde

Ok i will look at it thank you

Collapse
 
mellen profile image
Matt Ellen-Tsivintzeli

I could be wrong, prehaps your security model is that anyone can use firebase with your credentials, in which case nevermind, but it seems reckless to put your API key in the open like that.

Collapse
 
applicafroguy profile image
Sivuyile Magutywa

The Firebase config object contains unique, but non-secret identifiers for your Firebase project. From Google,

you can checkout this article

Collapse
 
varshithvhegde profile image
Varshith V Hegde

Thank you 👍

Collapse
 
varshithvhegde profile image
Varshith V Hegde • Edited

I dont think i have made my api public bcz in the repo which i hace kept the code i removed the api key and all credentials and even if the account gets hacked it 's my test account. And i have set some functions for autodelete so no worries.

Collapse
 
mellen profile image
Matt Ellen-Tsivintzeli • Edited

You API key is visible on your website, in the script.js file. It ends "NqAHfM".

If it's your test account, then that's probably fine.

Thread Thread
 
Sloan, the sloth mascot
Comment deleted
 
varshithvhegde profile image
Varshith V Hegde • Edited

If you have any idea to close this loop hole you can give me. It would be great help👍

Thread Thread
 
mellen profile image
Matt Ellen-Tsivintzeli

I can't see a way to do it with a pure frontend application. Your users will always download the API key one way or another if it's in the client side JS.

If you don't want users to have access to the key then you'd need to send their file to a server and have the backend store the file to firebase and return the file id. Maybe you can do it with an AWS lambda function?

Thread Thread
 
varshithvhegde profile image
Varshith V Hegde

Hello, now even if my api key is public no one else can't use because i have given restriction to api key so that if the api key is used in my domain then only it will be working else its just a useless string. 😅

Thread Thread
 
mellen profile image
Matt Ellen-Tsivintzeli

That sounds like a good solution

Thread Thread
 
varshithvhegde profile image
Varshith V Hegde

yeah, you just made me research me and my friend about it for about half a day, and thanks to you for pointing it out.

Collapse
 
leopold profile image
Leopold • Edited

Sharing the file with a 5 digits number feels a bit meh for me, what about asking the user to enter a password to secure his file ? I think this is a more elegant way to handle this, also you make the user more responsible to protect his own file. Other than that cool work, I like the concept!

Collapse
 
varshithvhegde profile image
Varshith V Hegde

Yeah i am going to add that feature. If the user wants his file to nore secure he can use his own password or he can just use random number to share it with his friends so they can download it from the server.

Collapse
 
hacknetayush profile image
HackNetAyush

What if anyone keep uploading files (like spamming) and never download them .... then your firebase storage will be full. Because you wrote

 ref.child(childSnapshot.key).remove()
Enter fullscreen mode Exit fullscreen mode

In the downloding section....

But the better method is that you should limit the file size and no. of uploads for each IP address. And then you can also put time of 24hrs or anything else to delete those files regularly.

Collapse
 
varshithvhegde profile image
Varshith V Hegde

It's in auto delete of 24hrs😅😂 and file upload limit is 25 MB

Collapse
 
hacknetayush profile image
HackNetAyush

Then fine 😄

Collapse
 
stefnotch profile image
stefnotch

This isn't safe at all. I can enumerate all files by using

ref = firebase.database().ref("image");
ref.on("value", function(snapshot) {
        snapshot.forEach(function(childSnapshot) {
        var childData = childSnapshot.val();
        console.log(childData.url);
        });
    }
    );
Enter fullscreen mode Exit fullscreen mode

(Bad code style, I know)

Also, using 5 digits means that you've got 100000 (one hundred thousand) different files that you can upload at a time. So if it becomes more popular, you'll quickly end up in a situation where uploads can randomly fail or overwrite other people's work. Worse yet, it'll become quite easy to accidentally find other people's stuff.

Heck, if I wanted to mess with people, I'd upload a few hundred zip bombs (substitute for worse options) to the site and wait.

If you want any semblance of private urls, generating a UUID is the easiest option. These days, there's even developer.mozilla.org/en-US/docs/W... . (And feel free to ignore old iOS Safari versions, they suck and nobody should be using them.)

Collapse
 
varshithvhegde profile image
Varshith V Hegde

Yeah i know there are lot of loop holes. At first because it's firebase free tier there is a possibility of limited read write. And the storage is also very less that's why i have kept the file sixe less tgan 25 MB and codee style because i am not a pro at this time I focused more on functionality rather code itself. So these may be the reason. Thank you for your suggestion it's great to see you took time to explain this to me. 👍🔥

Collapse
 
mrinjamul profile image
Injamul Mohammad Mollah • Edited

You can take a look at this github.com/chroline/lightning-share .
What do you mean by "Secure file sharing"?
It's not secure at all, we can always crawl back to get all the files. As we are giving access to the database.

Collapse
 
varshithvhegde profile image
Varshith V Hegde

Nice one bro

Collapse
 
joe_codes1 profile image
Joe Code

Good work I want to ask what happens if the receiver are much and they want to download the file at a time what happens if one receiver download with the unique ID since once the unique ID is used the file will be deleted from firebase

Collapse
 
varshithvhegde profile image
Varshith V Hegde

Yeah actually it is simple one to one file sharing so it's serves the purpose!!

Collapse
 
shinjithdev profile image
shinjith

Excellent work!

I attempted to download the file that I had uploaded, but it instead opened the file. Was that on purpose?

Collapse
 
varshithvhegde profile image
Varshith V Hegde

Yes as well as no. it was on purpose in order to auto delete it actually need to run the function so i thought to open it on new page would help. And also no because other options are not working for me. If you know any method to download a file from a link directly you can suggest me. I would be very grateful to use it.

Collapse
 
shinjithdev profile image
shinjith • Edited

Not sure how well this solution works,

<button>
    <a
        href="<ref link to file>"
        download="<file name and format on download>"
        onclick="showFile()"  //function to execute on clicking
    >
       Download
    </a>
</button>
Enter fullscreen mode Exit fullscreen mode

You can research more about this :). Hope this is useful.

Collapse
 
varshithvhegde profile image
Varshith V Hegde

Thank you for your great suggestion. I will surely look through it. Try to add with pack of features. Keep supporting. 😊

Some comments have been hidden by the post's author - find out more