Search code examples
firebasegoogle-cloud-functionsfirebase-storage

Uploading files from Firebase Cloud Functions to Cloud Storage


The documentation is too complex for me to understand. It shows how to download a file from Cloud Storage to Cloud Functions, manipulate the file, and then upload the new file to Cloud Storage. I just want to see the basic, minimum instructions for uploading a file from Cloud Functions to Cloud Storage. Why doesn't this work:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp();

exports.storage = functions.firestore.document('Test_Value').onUpdate((change, context) => {

  var metadata = {
    contentType: 'text',
  };

  admin.storage().ref().put( {'test': 'test'}, metadata)
  .then(function() {
    console.log("Document written.");
  })
  .catch(function(error) {
    console.error(error);
  })

});

The error message is admin.storage(...).ref is not a function. I'm guessing that firebase-admin includes Firestore but not Storage? Instead of firebase-admin should I use @google-cloud/storage? Why doesn't this work:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

const {Storage} = require('@google-cloud/storage')();
const storage = new Storage();

admin.initializeApp();

exports.storage = functions.firestore.document('Test_Value').onUpdate((change, context) => {

  storage.bucket().upload( {'test': 'test'} , {
    metadata: {
      contentType: 'text'
    }
  })

});

I can't even deploy this code, the error message is

Error parsing triggers: Cannot find module './clone.js'

Apparently a npm module dependency is missing? But the module isn't called clone.js? I tried requiring child-process-promise, path, os, and fs; none fixed the missing clone.js error.

Why does admin.initializeApp(); lack parameters, when in my index.html file I have:

firebase.initializeApp({
    apiKey: 'swordfish',
    authDomain: 'myapp.firebaseapp.com',
    databaseURL: "https://myapp.firebaseio.com",
    projectId: 'myapp',
    storageBucket: "myapp.appspot.com"
  });

Another issue I'm seeing:

npm list -g --depth=0       

/Users/TDK/.nvm/versions/node/v6.11.2/lib
├── [email protected]
├── UNMET PEER DEPENDENCY  error: ENOENT: no such file or directory, open '/Users/TDK/.nvm/versions/node/v6.11.2/lib/node_modules/firebase-admin/package.json
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

In other words, there's something wrong with firebase-admin, or with Node 6.11.2. Should I use a Node Version Manager to revert to an older version of Node?


Solution

  • I uploaded a file from my hard drive to Firebase Cloud Storage via Google Cloud Functions. First, I found the documentation for Google Cloud Functions bucket.upload.

        const functions = require('firebase-functions');
        const admin = require('firebase-admin');
        admin.initializeApp();
        
        exports.Storage = functions.firestore.document('Storage_Value').onUpdate((change, context) => {
        
          const {Storage} = require('@google-cloud/storage');
          const storage = new Storage();
          const bucket = storage.bucket('myapp.appspot.com');
        
          const options = {
            destination: 'Test_Folder/hello_world.dog'
          };
        
          bucket.upload('hello_world.ogg', options).then(function(data) {
            const file = data[0];
          });
        
          return 0;
        });
    

    The first three lines are Cloud Functions boilerplate. The next line

        exports.Storage = functions.firestore.document('Storage_Value').onUpdate((change, context) => {
    

    creates the Cloud Function and sets the trigger. The next three lines are more Google Cloud boilerplate.

    The rest of the code locates the file hello_world.ogg on my computer's hard drive in the functions folder of my project directory and uploads it to the directory Test_Folder and changes the name of the file to hello_world.dog in my Firebase Cloud Storage. This returns a promise, and the next line const file = data[0]; is unnecessary unless you want to do something else with the file.

    Lastly we return 0;. This line does nothing except prevent the error message

    Function returned undefined, expected Promise or Value