Search code examples
firebasefileunity-game-enginegoogle-cloud-firestoreupload

How to upload files to firebase storage using rest api in unity


I want to upload files to firebase storage using the rest API from unity. It is like clicking the browse button, browsing on local storage, selecting files, and then uploading.

How do I do this?


Solution

  • Create a cloud function with busyboy

    • Create a sample firebase function

    • Copy the code for package.json

    • Run the command to install the node modules

      npm run
      
    • Copy the code for index.js

    • To generate a private key file for your service account:

      • In the Firebase console, open Settings > Service Accounts.

      • Click Generate New Private Key, then confirm by clicking Generate Key.

      • Choose Node Js

      • Securely store the JSON file containing the key.

    • Copy the firebase-admin-sdk.json file inside the function directory

    • Deploy the function to firebase

      firebase deploy --only functions
      
    • Get the http endpoint from the firebase console

    Index.js

    const functions = require("firebase-functions");
    const os = require("os");
    const path = require("path");
    const spawn = require("child-process-promise").spawn;
    
    //To enable Cross AXIS 
    //Change to False to avoid DDOS
    const cors = require("cors")({ origin: true });
    
    //Parse Files
    const Busboy = require("busboy");
    
    //Files System
    const fs = require("fs");
    
    var gcconfig = {
        // Get the project ID from firebaserc
      projectId: "<project_id>",
    //   Write the name of the file in the root director which contains the private key of firebase-admin-sdk
      keyFilename: "firebase-admin-sdk.json"
    };
    
    // const gcs = require("@google-cloud/storage")(gcconfig);
    const {Storage} = require('@google-cloud/storage');
    const gcs = new Storage(gcconfig);
    
    exports.uploadFile = functions.https.onRequest((req, res) => {
    
      //Allowing CROSS SITE
      cors(req, res, () => {
        if (req.method !== "POST") {
          return res.status(500).json({
            message: "Not allowed"
          });
        }
    
        console.log("Starting BusBOY");
        const busboy = Busboy({ headers: req.headers});
        let uploadData = null;
        
        //File parsing
        busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
    
            // Firebase cloudfunction will have some tmpdirectory tmpdir
            // It will be cleaned up after execution
          console.log("File function reached ");
    
          console.log("Temp folder is "+os.tmpdir());
          console.log("File name is "+filename.filename);
    
          const filepath = path.join(os.tmpdir(),filename.filename);
    
          console.log("Location of file is "+filepath);
          uploadData = { file: filepath, type: mimetype };
    
          console.log("Writing to temp file storage");
          //Writing file to storage
          file.pipe(fs.createWriteStream(filepath));
    
          //Extra Details such as limit error
          file.on('limit', () => {
            console.log("Reached size limit");
            debugLog(options, `Size limit reached for ${field}->${filename.filename}, bytes:${getFilesizeInBytes(filename)}`);
          });
            file.on('end', () => {
            const size = getFilesizeInBytes(filename.filename);
            console.log("File size is "+size+" bytes");
           });
           file.on('error', (err) => {
            console.log("File format error");
           });
    
        });
    
        //For Form data Listener
        // busboy.on("field",()=>{
    
        // });
    
        // Finishes the whole process, only upload after that
        busboy.on("finish", () => {
    
            // Firebase storage, Inside the console itself
            // Copy the folder location
            // gs://<Project_id>.appspot.com
            // Remove the gs String
    
          console.log("Finished BusBoy");
          var your_project_id="<your_project_id>.appspot.com";
    
          const bucket = gcs.bucket(your_project_id);
          console.log("Uploading Image to firebase");
          
          bucket
            .upload(uploadData.file, {
              uploadType: "media",
              metadata: {
                metadata: {
                  contentType: uploadData.type
                }
              }
            })
            .then(() => {
                // Success
              console.log("Uploaded Successfully");
              res.status(200).json({
                message: "It worked!"
              });
            })
            .catch(err => {
                // Error
                console.log("Error while uploading");
    
              res.status(500).json({
                error: err
              });
            });
        });
    
        //End the parsing
        console.log("End Parsing");
        busboy.end(req.rawBody);
    
      });
    });
    
    //Finding the file size from the filename
    function getFilesizeInBytes(filename) {
      var stats = fs.statSync(filename);
      var fileSizeInBytes = stats.size;
      return fileSizeInBytes;
    }
    

    package.json

    {
      "name": "functions",
      "description": "Cloud Functions for Firebase",
      "scripts": {
        "serve": "firebase emulators:start --only functions",
        "shell": "firebase functions:shell",
        "start": "npm run shell",
        "deploy": "firebase deploy --only functions:uploadFile",
        "logs": "firebase functions:log"
      },
      "engines": {
        "node": "14"
      },
      "main": "index.js",
      "dependencies": {
        "firebase-admin": "^9.8.0",
        "firebase-functions": "^3.14.1",
        "@google-cloud/storage": "^6.0.1",
        "busboy": "^1.6.0",
        "child-process-promise": "^2.2.1",
        "cors": "^2.8.5"
      },
      "devDependencies": {
        "firebase-functions-test": "^0.2.0"
      },
      "private": true
    }
    
    

    For more details

    Checkout https://github.com/katmakhan/firebase-course/tree/master/Firebase%20Cloud%20Function/Image%20Uploader