how to test Cloud Functions for Firebase locally on pc

浪尽此生 提交于 2019-11-26 12:19:06

问题


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.

It looks like it bundles all dependencies and upload it to firebase just like aws lambda function does. But it takes too much time to be done even on minor changes in code and also need a good connectivity of internet . If you are offline for some reason, you are just in dark what code you are writing until you have a way to execute and test that functions offline on your local machine.

Is there any way to test Cloud Functions for Firebase locally?


回答1:


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.




回答2:


firebaser here

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




回答3:


run and debug/inspect functions locally

prerequisites (google-cloud functions and firebase-specific):

npm install -g @google-cloud/functions-emulator
npm install --save firebase-functions
npm install -g firebase-tools

To run and inspect/debug: first run functions locally, then inspect each function, and finally run each specific function to debug+inspect it. Use functions start as an alternative to firebase serve and note the documentation for each tool is available (and useful).

To run and debug the specific function myFn as-expected (eg in Nodejs via chrome://inspect and note this works using Nodejs v10 though not officially supported):

firebase serve --only functions
functions inspect myFn
functions call myFn # or call from browser

additional documentation:

https://firebase.google.com/docs/functions/local-emulator https://cloud.google.com/functions/docs/emulator#debug-emulator https://github.com/GoogleCloudPlatform/cloud-functions-emulator/wiki




回答4:


Answered here: https://github.com/firebase/firebase-functions/issues/4#issuecomment-286515989

Google Cloud Functions also open-sourced a local emulator, and we are working to build a tighter integration with Cloud Functions for Firebase. In the meanwhile, you can check it at here: https://github.com/GoogleCloudPlatform/cloud-functions-emulator/

The emulator does allow you to run functions locally. Here's the documentation that explains how to use it: https://cloud.google.com/functions/docs/emulator




回答5:


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.




回答6:


Firstly, I suggest you to install following dependencies,

npm install --save firebase-functions
npm install -g firebase-tools 

If already installed then you can update it to latest one. Generally, functions-emulator comes with above dependency but still I would recommend you to update it,

npm install -g @google-cloud/functions-emulator

Once it has been updated, go to functions folder of you application and run following command,

firebase serve --only functions

I hope it helps!




回答7:


For vscode users debugging HTTP functions (webhooks, etc)...

The google cloud emulator (firebase serve --only functions) launches a separate process to run your functions. You can attach to this process with vscode, but since the emulator only creates this process after the first function is called, it's not straightforward.

  • create a dummy HTTP endpoint in your functions which will return the processID:
app.get("/processid", function(request, response) {
  response.send(`${process.pid}`);
});
  • start the emulator with firebase serve --only functions
  • call the http://<localhost_url>/processid endpoint. This will create the process and return the processID
  • use vscode to attach to the specified process. You can now set breakpoints, step, etc on any of the other functions (they all use the same process).

There's probably a nicer way to glue all this together.




回答8:


There is now a cloud functions emulator that lets you call functions locally

Once I have completed my PoC I will update this answer to include code and steps I used.



来源:https://stackoverflow.com/questions/42726310/how-to-test-cloud-functions-for-firebase-locally-on-pc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!