Firebase emulator for Cloud Functions not updating the code - firebase

I'm deploying the following cloud function using firebase deploy --only functions :
export const testFunction = functions.https.onCall((data, context) => {
return {"data": "hello"};
});
and when call it from the client app using the code
var testFunction = firebase.functions().httpsCallable("testFunction");
testFunction().then((result) => {
// Read result of the Cloud Function.
this.data = result.data;
});
it works as expected.
Now, I want to continue developing the function testing it on the local emulator so, following the documentation, I added this line to the web app code (before the function)
firebase.functions().useEmulator("localhost", 5001); // for local simulator
and I run the local emulator with:
firebase emulators:start --only functions
If I run the client app now, I correctly see the call going through the local emulator instead of the remote cloud function.
Problem: If modify the code the local function doesn't get updated. I need to run firebase deploy again in order to see the change in the response. How can I just deploy locally?

This stackoverflow solves the issue.
Solution in short:
After every change in your code, run npm run build to recomplie the code.
To auto-compile for every change in your code.
Change "build": "tsc" to "build": "tsc -w" in your package.json
file, and run the emulator in an another terminal window.

You can use the functions shell as described in this documentation here in order to deploy, run and test functions locally. I find the documentation quite confusing, as it only mentions how to use .sh scripts to test locally.
firebase functions:shell
Note that if you use the shell, you don't need to run the emulators separately; the shell will run them for you. The shell will automatically update based on changes to the index.js functions file, but if you're using TypeScript you may have to rebuild after you make changes. This is typically done by going into the functions directory and running npm run build. You can also automate this as well, according to this answer, but I haven't tried this approach yet.

Related

Firebase deploy failed even without changing the function from onCallable to onRequest

Error: [functionName(us-central1)] Changing from a callable function to an HTTPS function is not allowed. Please delete your function and create a new one instead.
Any advice and insight is appreciated.
Which version of Firebase CLI (firebase --version) are you using? Last night I updated firebase-tools package to 10.3.0 and functions deployment started giving me the error you mention. I downgraded to 10.2.2 and functions deployment started working as before.
Update:
Firebase team confirmed there is an issue with 10.3.0 firebase-tools. They are working on a fix:
https://github.com/firebase/firebase-tools/issues/4307
Solution 01:
I think the main problem lies inside whether you are using a valid way to use .env file. Since I just recently have this kind of error. If you do use the .env file inside the structure of your folder, then
You need to declare the path to .env file in all files which uses process.env.VARIABLE_NAME. Example way is like this:
require("dotenv").config({path: "../.env"});
After that try to delete all existing Cloud Functions in Google Cloud Console
Try deploy again: firebase deploy --only functions
I added a path to the .env file, since I checked Firebase Cloud Function Logs and it gave me error for all Cloud Functions which uses process.env.VARIABLE_NAME. This .env file must be located inside the root project and placed inside folder functions/. Give it a try. Hope it works.
Solution no. 2:
You should check if there is a variable or function which doesn't give return value, like example below:
const key = async () => {
const response = await pk.accessSecret("PRIVATEKEY");
return response;
};
I forgot to add a return value from the variable const key. Therefore I get so many errors like you do in all of my functions. And that errors cause firebase cli to state"
Changing from a callable function to an HTTPS function is not allowed.
Please delete your function and create a new one instead.
this happened to me as well. npm i -g firebase-tools#latest did the trick.

How much is deployed while deploying a specific firebase cloud function?

If I have a firebase cloud function like this:
exports.exampleFunction = function (admin, envKey) {
return functions..https.onRequest((req, res) => {
doSomething(req)
}
}
And I modify the doSomething function and deploy exampleFunction with:
firebase deploy --only functions:exampleFunction
Will the modifications to doSomething be included in the deployment? This is a trivial example - but more generally - does Firebase track the dependencies of a function when it is deployed? Or do I need to deploy all functions in order to push modifications to dependencies?
Firebase has no way to introspect the workings of your code to understand what has changed or hasn't, so every deploy deploys all files in the functions directory to be rebuilt. Using the --only flag controls which functions will actually be updated, but the same source code is used to build and deploy each function regardless of flags.

Issue running cloud functions code locally using cloud functions shell

I am trying to test my functions locally using cloud functions shell. I was successful in making the shell thing work for my code. I see that this doesn't require my code to be deployed to the cloud. But whenever I run the function through shell it's working fine but it is using the deployed code, not the local code(I am checking this by using console statements as shown in sample code). I am not able to invoke local code unless I deploy.
Also, in my cloud functions, I am using the onCreate method for a real-time database and writing back to the same real-time database. When I test locally using the shell, I input data files for the function and write back to the real-time database. So I am actually trying to write code and run it locally to write to a real-time database on the cloud. Is this achievable using shell without deploying functions?
My sample function looks like this:
export const myCloudFunction = functions.database.instance(getDatabaseIdentifier()).ref(PATH).onCreate(async (snapshot, context) => {
console.log('local code invoked')
// or
console.log('deployed code invoked')
});
I figured it out since I am using typescript I need to transpile my code to javascript before I run the cloud functions shell.
The reason I thought it's invoking the deployed code is obvious as it is not actually invoking the deployed code but invoking the locally transpiled code which gets generated while I deploy to cloud. Now all I needed to do is transpile my code using the below command in my functions folder before I run the cloud functions shell.
// run this command in your functions folder
'npm run-script build'
This build generates transpiled javascript code in the 'lib' folder. Now we can run the below command to invoke the shell.
firebase functions:shell
Now we can emulate the local non deployed cloud functions and test them locally.
Check this medium post for detailed explanation:
https://medium.com/#moki298/test-your-firebase-cloud-functions-locally-using-cloud-functions-shell-32c821f8a5ce

After following all instructions for migrating to Firebase Cloud Functions 1.0, deployment fails

I'm attempting to migrate my Firebase Cloud Functions installation up to the newly released V1.0.
I've carefully followed all instructions provided at
https://firebase.google.com/docs/functions/beta-v1-diff , including including running the updates and also going through every function I have to make sure it reflects the changes in v1 which break old functions.
When I then attempt to run a deploy (for functions only), I get the following error: Error:
Invalid Firebase app options passed as the first argument to initializeApp() for the app named "[DEFAULT]". The "credential" property must be an object which implements the Credential interface.
Notably, there is a specific mention of no longer needing to provide the credentials in the argument: "firebase-admin is now initialized without any parameters within the Cloud Functions runtime."
My suspicion is the update to Firebase Cloud Functions (npm install firebase-functions#latest --save) didn't succeed. I suspect this because, although there's a lot of activity after that call, the output is just two lines:
Brandus#1.0.0 /Users/ajr/Documents/dev/sites/Brandus
└── firebase-functions#1.0.0
I've seen another question with the same symptoms: Cloud Functions Firebase v1.0. I tried to comment but my reputation is too low.
Edit: code as requested
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require( 'firebase-functions' ) ;
var fs = require('fs');
var url = require('url');
var http = require('http');
var https = require('https');
// tinycolor2
const tinycolor = require( 'tinycolor2' ) ;
// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require( 'firebase-admin' ) ;
//admin.initializeApp(functions.config().firebase);
admin.initializeApp();
That's all the code up to the point where the error is, with the previous code commented out.
I had the same problem. As suggested by Bob Snyder in one of the comments, I checked my versions in package.json and firebase-admin was still to an old version. After setting it to ^5.11.1 and running "npm install" in the functions folder, I was able to deploy right away. I did not have to change the project to TypeScript.
You could just run npm install --save firebase-admin#latest in the functions folder instead. Better this way, no arbitrary version to specify.
I was able to successfully deploy after changing my project to use TypeScript instead of Javascript. The functions appear to be working correctly after the deployment.
I followed these instructions to complete the migration.
It's possible a fresh firebase init would have fixed it even without the migration to typescript, but either way, this worked for me.

Can not see the Firebase function deployed

I followed the following steps:
The Firebase CLI (Command Line Interface) requires Node.js and npm, which you can install by following the instructions on https://nodejs.org/
Installing Node.js also installs npm
Once you have Node.js and npm installed, install the Firebase CLI via npm:
npm install -g firebase-tools
This installs the globally available firebase command. To update to the latest version, re-run the same command
Initialize your project:
a. Run firebase login to log in via the browser and authenticate the firebase tool.
b.Go to your Firebase project directory or create the directory
c. Run firebase init functions
The tool gives you an option to install dependencies with npm. It is safe to decline if you want to manage dependencies in another way.
Select associated firebase project
Select Y to install dependencies with npm
Move to directory setup firebase functions
Edit index.js file with the function you created
Run the firebase use --add to add your Firebase project
Run firebase deploy --only functions to deploy the function
After all this I get the message in the terminal at deploy was completed but in the Firebase console, when i click on Functions tab there are no functions listed!?
Quick Tip: Make sure you are exporting the function you are trying to deploy in your index.js file. Your firebase project will deploy but Cloud Functions won't be available unless they are exported.
Make sure you save the file after uncommenting the default function and then use
firebase deploy
For Cloud Functions, it is required to add your function to the special exports object (it is a Node's way of making the function accessible outside of the current file)
Make sure to have index.js in your functions directory:
Example of a function:
// Import the Firebase SDK for Google Cloud Functions.
const functions = require('firebase-functions');
// Import and initialize the Firebase Admin SDK.
const admin = require('firebase-admin');
admin.initializeApp();
// Your function declaration. Example of a fired function when a user is created in Auth feature.
exports.myFunction = functions.auth.user().onCreate(async (user) => {
// ... your code here.
});
Then for deployment follow these steps:
First, if not done, make sure to have firebase-tools installed:
$ npm install -g firebase-tools
And initialised: $ firebase init
For full deployment:
$ firebase deploy
OR for functions deployment
$ firebase deploy --only functions
OR to deploy specific functions
$ firebase deploy --only functions:function1,functions:function2
A good read with a very useful example: https://codelabs.developers.google.com/codelabs/firebase-cloud-functions/#7
I went through the same issue recently, while performing Actions on Google Node.js Client Library Version 1 Migration Guide. to Node.js Client Library V2 (That I highly recommend) It took me a while to figure out what what was happening. At the I couldn't really figure out what the problem was! So here is what I did and it worked for me:
Make sure you have a backup copy of your cloud functions (index.js) and maybe your package.json (Just in case you don't want to remember what packages you previously had installed - Could be annoying sometimes).
Delete the entire functions directory from your project folder.
Re-launch firebase CLI with firebase init and choose Functions
Once your cloud function have been initialized, CD into the functions folder and Redeploy it using firebase deploy --only functions.
If everything goes well 😃, you should now see your function deployed on your firebase dashboard console.
N.B: Google recently released the Node.js Client Library version 2 (v2) in April 16th 2018 with a lot of new features. After April 16th, 2018, new features on Actions on Google will no longer be added to v1 of the client library. If you want to use new features, you must migrate to v2 client library.
In addition, the v1 client library does not support Dialogflow v2. If you need Dialogflow v2 functionality, you’ll also need to migrate to v2 of the client library.
Hope this helps 👍.
In step 7, you have to uncomment the sample function in there and save the file. Then, in the output of the deploy command, you will be given a url for the created helloWorld function.
I had exactly the same problem and I solved it by making sure the index.js file containing all my functions was saved on the "functions" folder inside the project folder. I am using vs code so I just clicked on file/save as and selected the correct folder.
#Learn2Code
I had the exact same issue.
Ensure that in your index.js file, you export your function before initializing your app.
Now, go ahead and run firebase deploy from your project directory.
For example:
// Take the text parameter passed to this HTTP endpoint and insert it into the
// Realtime Database under the path /messages/:pushId/original
exports.addMessage = functions.https.onRequest(async (req, res) => {
// Grab the text parameter.
const original = req.query.text;
// Push the new message into the Realtime Database using the Firebase Admin SDK.
const snapshot = await admin.database().ref('/messages').push({original: original});
// Redirect with 303 SEE OTHER to the URL of the pushed object in the Firebase console.
res.redirect(303, snapshot.ref.toString());
});
const admin = require('firebase-admin');
admin.initializeApp();
Make sure you're running at least version 3.5.0 of firebase-tools. To check which version you have, run:
firebase --version
If you're running the default setup, you can update firebase-tools using:
npm install -g firebase-tools
Had the same situation. The problem was that when I was doing
$ firebase deploy --only "myFunction"
That filter name: myFunction, was not exactly the same as the name of the function I was trying to deploy. Silly mistake but took me a day to realize...
To clarify one issue - it appears as though your index.js file inside the functions folder must export functions created within the same file (similar to what Fran had said).
It seems trying to organize your files into subfolders will not work properly with Firebase functions - same rules apply for using firebase serve to test locally (must create codeinside functions/index.js).
Hope this helps someone!
1) Make sure you are exporting the function you are trying to deploy in your index.js file.
2) Write 'use-strict' at the top of your file (index.js) then use console to deploy your function
Check your "default project" at firebase init. Select one with similar name was my mistake. ;)
Use firebase projects:list and firebase use <project> to make sure the Firebase CLI's "current project" is set correctly regardless of what folder you're in.
Example:
> firebase projects:list
✔ Preparing the list of your Firebase projects
┌──────────────────────┬─────────────────────┬──────────────────────┐
│ Project Display Name │ Project ID │ Resource Location ID │
├──────────────────────┼─────────────────────┼──────────────────────┤
│ alpha │ alpha (current) │ [Not specified] │
├──────────────────────┼─────────────────────┼──────────────────────┤
│ beta │ beta │ [Not specified] │
└──────────────────────┴─────────────────────┴──────────────────────┘
2 project(s) total.
> firebase use beta
Now using project beta
I had this error as well. I had copied a working function running on Google Cloud Functions from a previous project and could not figure out why it would not show up once deployed.
I needed to wrap my function in functions.https.onRequest(), which is not required on normal cloud functions.
Had the same issue.
In my case solved by using firebase deploy wihtout any --only, which revealed better error messaging and I had to setup billing in Cloud Console for the project. The setup routine can be triggered by selecting Could Functions in the Console.
I had another issue in which the Service Account was missing from the Project, so I setup a fresh project through the Console first and then added this to Firebase.
Make sure you init firebase on step back from your firebase functions. and also firebase functions name must be functions.
It works for me
One dumb gotcha I just ran into, I was running "firebase deploy" from the top level folder (one above the /functions sub-folder), and it deployed "successfully" but I never saw it in Firebase itself. It wasn't until I cd'd into /functions and re-ran firebase deploy that the full deployment actually worked.

Resources