how to test Cloud Functions for Firebase locally on pc

前端 未结 9 1447
耶瑟儿~
耶瑟儿~ 2020-11-27 16:39

Today Firebase released its brand new product Cloud Functions for Firebase and I just created a hello world function and deploy it on my existing firebase project.

I

相关标签:
9条回答
  • 2020-11-27 17:13

    firebaser here

    To debug your Cloud Functions for Firebase locally, there is an emulator. See the documentation for more info.

    0 讨论(0)
  • 2020-11-27 17:17

    I couldn't get the single stepping working at first. My process was the same as documented in many answers here.

    Also, these pages contain nearly all the documentation I required:

    • https://firebase.google.com/docs/functions/local-emulator
    • https://cloud.google.com/functions/docs/emulator#debugging_with_the_emulator

    I had got the functions running using firebase serve --only functions, but hadn't got the debugger up and running. Then I came across the other way of directly using the emulator and managed to hit a break point like this:

    # start the emulator
    functions start
    
    # allow inspection
    functions inspect helloWorld
    
    # call the function from the cli
    functions call helloWorld
    

    This worked, and I could hit a breakpoint.

    However, when hitting the endpoint for the function in postman or the browser, I got no response at all.

    The step I was missing was:

    # deploy the function to the emulator
    functions deploy helloWorld --trigger-http
    
    # you need to toggle inspection after the deploy
    functions inspect helloWorld
    

    Now I can hit the endpoint for the function from postman or the browser, and the breakpoint is hit.

    I recommend the brilliant NiM chrome extension for debugging and hope this answer helps someone, even if this is an old question.

    0 讨论(0)
  • 2020-11-27 17:22

    firebaser here

    Deployment of your Functions indeed takes more time than what I'm normally willing to wait for. We're working hard to improve that and (as Brendan said) are working on a local emulator.

    But for the moment, I mostly write my actual business logic into a separate Node script first. That way I can test it from a local command prompt with node speech.js. Once I'm satisfied that the function works, I either copy/paste it into my actual Functions file or (better) import the speech module into my functions file and invoke it from there.

    One abbreviated example that I quickly dug up is when I was wiring up text extraction using the Cloud Vision API. I have a file called ocr.js that contains:

    var fetch = require('node-fetch');
    
    function extract_text(url, gcloud_authorization) {
      console.log('extract_text from image '+url+' with authorization '+gcloud_authorization);
    
      return fetch(url).then(function(res) {
        return res.buffer();
      }).then(function(buffer) {
        return fetch('https://vision.googleapis.com/v1/images:annotate?key='+gcloud_authorization, {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify({
            "requests":[
              {
                "image":{
                  "content": buffer.toString('base64')
                },
                "features":[
                  {
                    "type":"TEXT_DETECTION",
                    "maxResults":1
                  }
                ]
              }
            ]
          })
        });
      }).then(function(res) {
        var json = res.json();
        if (res.status >= 200 && res.status < 300) {
          return json;
        } else {
          return json.then(Promise.reject.bind(Promise));
        }
      }).then(function(json) {
        if (json.responses && json.responses.length && json.responses[0].error) {
          return Promise.reject(json.responses[0].error);
        }
        return json.responses[0].textAnnotations[0].description;
      });
    }
    
    if (process.argv.length > 2) {
      // by passing the image URL and gcloud access token, you can test this module
      process.argv.forEach(a => console.log(a));
      extract_text(
        process.argv[2], // image URL
        process.argv[3]  // gcloud access token or API key
      ).then(function(description) {
        console.log(description);
      }).catch(function(error) {
        console.error(error);
      });
    }
    
    exports.extract_text = extract_text;
    

    And then in my Functions index.js, I have:

    var functions = require('firebase-functions');
    var fetch = require('node-fetch');
    var ocr = require('./ocr.js');
    
    exports.ocr = functions.database().path('/messages/{room}/{id}').onWrite(function(event) {
      console.log('OCR triggered for /messages/'+event.params.room+'/'+event.params.id);
    
      if (!event.data || !event.data.exists()) return;
      if (event.data.ocr) return;
      if (event.data.val().text.indexOf("https://firebasestorage.googleapis.com/") !== 0) return; // only OCR images
    
      console.log(JSON.stringify(functions.env));
    
      return ocr.extract_text(event.data.val().text, functions.env.googlecloud.apikey).then(function(text) {
        return event.data.adminRef.update({ ocr: text });
      });
    });
    

    So as you can see this last file is really just about wiring up the "worker method" ocr.extract_text to the database location.

    Note this is a project from a while ago, so some of the syntax (mostly the functions.env part) might have changed a bit.

    0 讨论(0)
提交回复
热议问题