Comments (51)
Hey malikasinger1, you can check out our documentation for how to write unit tests: https://firebase.google.com/docs/functions/unit-testing
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/
from firebase-functions.
Any update on the local Database events @laurenzlong?
Loving functions
overall, but developing is currently a nightmare..
from firebase-functions.
Hey Inzamam, thanks for the clarification. I accidentally copied and pasted the unit testing link twice. I've revised my response above. 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
from firebase-functions.
@stephenhandley Just released! https://github.com/firebase/firebase-tools/releases/tag/v3.8.0
Only HTTPS events for now, but other ones are coming!
from firebase-functions.
Thanks for following up @msjaber , we've done the first step, which is to enable the Google Cloud Functions emulator to support all event types: googlearchive/cloud-functions-emulator#121. You can use it now, and instructions are in the PR.
I'm now working on integrating this into the Firebase CLI, with a repl-like interface to invoke these emulated functions. I've been running several usability tests to make sure we get the experience right before releasing.
from firebase-functions.
I think the locally deployed database function should definitely listen on a real database rather than being invoked through some terminal command. Whether it listens on a production or test DB would be up to the developer, they should be able to choose which database by calling firebase use
before deploying locally.
I like @ahaverty's suggestion that when you run a database function locally, it could send a message to firebase to temporarily disable the cloud listener for the same function, and when the local function listener disconnects the cloud function automatically would take over again. That may not be necessary in all cases though, since it may be innocuous to have multiple listeners on the same node depending what the function does. Perhaps a command line switch could specify whether to temporarily disable the cloud function, and by default it would not. Something like:
firebase serve -disable-cloud --only functions:function1
This would disable the cloud listener of function1
, while function1
was being served locally. If there were a function2
in the cloud, the listener for function2
would not be affected.
If you omitted the -disable-cloud
switch, the cloud and local listeners for function1
would both be triggered.
If -disable-cloud
is invoked by two different developers on the same function at the same time, the second one should just see an error message that this action is currently disallowed because another -disable-cloud
is already being used on that function. Dev teams could avoid this scenario by using different test databases for different developers if they choose.
from firebase-functions.
Thanks for the feedback and lively discussion everyone!
I see people are divided on the issue of whether local functions should be triggered with the real database tied to the project. What if this was an opt-in behavior? It would not happen by default, but would only happen with an additional flag or something, so you are explicitly telling the CLI "This is not my production project, it is ok to trigger local functions with real database writes". And doing this would stop deployed functions from firing while the local functions are still running.
@fej-snikduj We'd be talking about months due to the complexity involved. I think we will likely do both (triggering local functions with mock events and with real database events). They serve slightly different use cases - mock events are great for testing without side effects, and real database is useful for end-to-end integration testing.
@atomicleopard thanks for the ambitious ideas! No ideas are too wild ;) In terms of breakpoints, we are actually working on supporting breakpoints in locally deployed functions so that you can debug them from an IDE.
@ahaverty Supporting json files is a great idea. If we were to do it, I'm thinking it would make the most sense to be consistent with the usage of firebase:database: commands. So it would look like:
firebase functions:invoke:makeUpperCase /input/path makeUpperCaseTest_valid.json
@mismith What do you think about invoking the function with sample foobar data if there was no data passed in via the flag? Trying to invoke it with the existing data would require the CLI to actually read the database to see what data is there -which would be slow. As well, the same data would not actually trigger the function, since only update/create/delete events will trigger a function.
from firebase-functions.
Hey @atomicleopard this is something that we are still working on. Stay tuned!
from firebase-functions.
@mismith
For #1, it depends on how you declared the function, if you had:
var functions = require('firebase-functions')
var createFunction = functions.database.ref('/path').onCreate(...)
var deleteFunction = functions.database.ref('/path').onDelete(...)
Then in the shell:
createFunction('new_data') // would mock a create event
deleteFunction('old_data') // would mock a delete event
As for auth, it is {admin: true} or {admin: false} or {variable: {uid: 'abcd' }},
from firebase-functions.
Thanks for the thorough feedback everyone! To answer your questions, a terminal command would probably look something like:
firebase serve
firebase functions:invoke:makeUpperCase /input/path -d '{"word":"foo"}'
Thanks for sharing the perspective that "intercepting" live traffic with a test function could be disastrous for teams. For testing against a real database, I imagine there being a test project that is the default project for "firebase serve". So both hosting and functions would use the test project. This way, you can test interactions like a) user fills out a form and that data gets stored to the database b) a function is invoked and transforms that input c) function writes back to the database d) the new database value affects the web page UI somehow.
The test project can be set using "firebase use --add", or maybe it can be a part of the "firebase init" flow. If a test project is not set, then "firebase serve" would use the production project but give a warning?? I'm not sure about what's best in that case.
Supporting the terminal command is achievable in the short term, but supporting real database triggers would take more time.
from firebase-functions.
from firebase-functions.
We're using separate projects for production/sales/Dev/Dev2 .
Dev2 if more than one of us are working on functions/rules simultaneously.
Local deployed (debuggable?) functions via Firebase tools cli (or IDE/IntelliJ support?) would be great, mainly to avoid the delays with deploying.
I can't imagine how this would work alongside remotely deployed functions, maybe you could give us an idea of how you're thinking of architecting it?
Could a local deployed function overrule a remote one? And automatically switch back on once it's killed locally? How would that work then with multiple local deployments? π€
Can't waitπ
from firebase-functions.
doing this would stop deployed functions from firing while the local functions are still running.
I love this idea. Especially if I could similarly pause deployed functions from running through an API or the Firebase console. While my returning of promises has improved, I still have the occasional deployed function go wild and it would be great to have a panic button. :-)
from firebase-functions.
I've developed firebase-functions-local to help with my own testing while the firebase team finishes off their own version.
It's handy because you can test without uploading the functions which makes the dev cycle much quicker. You can also attach a debugger to help you get a better idea of what is going on.
All triggers run off live data in the realtime database. If you have a smaller app you could even use this as the back-end for pesky functions that don't get touched often when you want to still have a lower response latency than the cloud function warmup time. Once they start getting hit often it's straightforward to migrate them to the cloud.
from firebase-functions.
Just made a PR to firebase-tools to the emulation of all even types, and a shell to invoke them: firebase/firebase-tools#428.
@Crazometer this is really neat! Thanks for sharing. My PR uses fake data, whereas yours uses real DB events, so they complement each other quite well and are useful for different scenarios.
from firebase-functions.
@laurenzlong I'm curious, so I looked over your PRβand maybe I'm missing something or confusedβbut why/how do the following two lines perform distinct actions?
# invoke onCreate function
myFunction('new_data')
# invoke onDelete function
myFunction('old_data')
i.e., why does the first invoke a create
while the second one a delete
? Is there a null
param missing maybe?
Also, is the following a typo or, if not, what does the auth
object need to contain?
# mock auth, for example: to mock unauthenticated user
myFunction('data', {auth, {admin: false}}
from firebase-functions.
If it works on firebase serve, it should work on the functions shell as well since the underlying emulation mechanism are the same. We haven't done a full survey of all IDEs to know that this would work properly on all of them, so there may be kinks. (But it is on our roadmap to address this and make sure breakpoints always work)
from firebase-functions.
Not yet. But coming soon.
from firebase-functions.
Thanks for the follow up! We're prototyping it right now. Would love everyone's feedback on how you would prefer to invoke the emulated database function. Would you rather it be listening to your production database? A test project's datebase? Invokable through a terminal command?
from firebase-functions.
+1 for through a terminal command
Thanks for the great work @laurenzlong
from firebase-functions.
That terminal command looks slick; I for one would definitely love to use it! Especially if the -d
flag is optional, and defaults to what is currently in the database at that location (i.e. it self-'refreshes' with existing data).
from firebase-functions.
@ahaverty Re: manual/invoked refresh: one of my functions sends an email whenever a key is updated (e.g. forms/<id>/submitAt
), so calling firebase functions:invoke:sendEmail /forms/<id>/submitAt
with no -d
flag would simply 're-submit' the form with the existing submitAt
datestring, thereby triggering my email and allowing me to debug that logic.
from firebase-functions.
@laurenzlong Thanks for all the updates. I completely agree with @jaufgang that a locally deployed database function should listen to a real database. I know that'll take a bit more time than the terminal commands, but I'm wondering if it's a priority and being worked on? If it's longer term, how long do you estimate until a solution is ready? Are we talking weeks or months?
from firebase-functions.
Thanks, @laurenzlong. Any updates for supporting database events?
from firebase-functions.
@mismith Oh yes, that is indeed a typo, sorry! It is a nested object: {auth: {admin: false}}
from firebase-functions.
@laurenzlong Is it possible to locally debug/breakpoint functions started by experimental:functions:shell
yet? (vscode)
It looks like it's possible for https functions using serve, but I haven't found anything about breakpointing realtime database functions, other than a few comments on this issue π.
~ I found this on google cloud functions debugging too. π€
from firebase-functions.
Thanks for clarifying, we don't yet support local testing of HTTP callable functions, but that's coming soon.
from firebase-functions.
@laurenzlong I realize this issue is years old, but I'm coming from GCF (and Functions Frameworks for local development) and now am writing my first Firebase Function as I want to listen for background events from my RTDB. In 2021 is there no way to listen for remote / production database events when using the emulator? Thank you.
from firebase-functions.
Dear @laurenzlong I was not talking about unit testing
I want to run firebase functions locally, just like we can run aws lambda function locally,
either it is possible right now?
if not, are you guise planning to give this facility in near future?
Thank you,
Inzamam Malik.
from firebase-functions.
How this emulator support the firebase specific parts of GCF (i.e. ref().onWrite()
? I haven't found any specific docs for this? Dev cycle while deploying up to the cloud is sort of excruciating, it would be great to be able to do this locally.
from firebase-functions.
hi @laurenzlong any updates on firebase integration in the emulator?
from firebase-functions.
@laurenzlong awesome thanks!
from firebase-functions.
@laurenzlong I'm using a separate 'root' within the same project (e.g. /production/data/1
vs. /development/data/1
) simply because this was the easiest to get up and running. It's definitely a tough problem to solve, and as you can already see, tons of different perspectives and alternatives to support. Maybe a terminal utility would make sense, something that kind of 'links' the path(s) being watched to the functions being called? e.g. maybe the dev can map which project/path/etc goes to which functions via some config file (with sensible/configless defaults, of course)? Even hardcoded JSON/dummy-data would potentially be better than nothing, at this point.
Btw, thanks for being so responsive and inclusive on this! π€ firebasers π€
EDIT: is this along the lines of what you mean by the terminal command?: firebase serve --only functions; firebase trigger-function "foo"
? or maybe something more generic with a custom path like firebase simulate-write --path="/foo/path/to/bar/with/function/watcher" --data-file="baz.json"
?
from firebase-functions.
Also, @laurenzlong, since this issue is actively being discussed and worked on, perhaps it should be re-set to open.... you closed it on March 13.
from firebase-functions.
I like the sound of that @jaufgang , perhaps cloud disabling true by default though as keeping cloud functions running wouldn't be a use case for us right now and may cause confusion with novice users in future (but we could live with either! π)
from firebase-functions.
@atomicleopard Firebase uses pub/sub for events, I've had functions fail before and still handle 100% of events, after coming back online after 1 hour. Although, I do agree with you, it could very easily get messy if one of the team left their local cloud-disabling test on and went out for an hour lunch break!
Pushing local data would be a great start, and would help testing the basics/syntax errors (currently 90% of our errors [we still haven't converted to typescript π’]). I imagine end to end testing would be more suitable for an online deploy anyway! Interested to hear what @laurenzlong thinks is even possible here
from firebase-functions.
@laurenzlong sounds good π
My vote is for simulating local events with -d, but default working with the 'production' database.
We're working on entirely separate firebase projects for multiple different projects (dev + our main production), so the test target wouldn't be as beneficial, but would also be no harm to have the option either.
..Unless I'm misunderstanding what 'test project' means? Does that mean another firebase project to target, or is it a local version of the Firebase database? If it's just a target option, wouldn't it make more sense for people to set up their target configurations properly and avoid the chance of writing to their production db's?
If a local Firebase database is possible, then yes! We could use that for a lot of different things (CI, simpler automated testing, reduce the number of dev projects)
from firebase-functions.
Would it be possible to add the ability to allow/disallow local testing against a real database using a new rule added to the rules.json? Either that or some other console setting? Production databases could be configured to disallow it, while dev/test databases could allow it.
Also, WRT @atomicleopard's concern about isolating problems if/when they occur, perhaps that could be mitigated by adding messages to the functions log whenever a local function attatches/detaches a listener.
from firebase-functions.
@mismith Interested to hear how/why the self-refresh would be beneficial for you? (assuming you mean take all the data at the defined ref and simulate pub/subs)
For us, it'd mean thousands of event writes would go off (Not currently removing our event writes as remove events currently retrigger the function and cost us another invocation. It might be useful once firebase implements specific event type functions, but even then you'd need to handle preventing triggers with the 'online' function, right?
Have you considered piping a cat command into -d
? @laurenzlong Could piping in file contents into -d
be considered as a use case for simpler testing/more complicated event writes?
Is it as simple as something like:
cat makeUpperCaseTest_valid.json > firebase functions:invoke:makeUpperCase /input/path -d
or could an explicit flag for file input be simpler?
firebase functions:invoke:makeUpperCase /input/path -f makeUpperCaseTest_valid.json
..Most of my testing involves creating it once via one of our client apps, exporting to json, and reimporting via the console. Not too bad right now, but this would be nice π
..Actually. @laurenzlong the ability to create a native firebase .push() on the path would be amazing too!
from firebase-functions.
from firebase-functions.
@laurenzlong I doubt the dummy data would be that useful (for me) since its form wouldn't be predictable, so I'd probably just end up using/generating my own and passing it via the JSON file or as an inline object.
The second half of your last paragraph is kind of worrisome though: if 'writing' the same exact data wouldn't trigger an onWrite
event, then wouldn't that mean that passing the same JSON file wouldn't either? Or event the same -d
data? In other words, I would expect that it should (in all these cases), so why not do the same with 'default path' dataβalbeit with the (presumably minor) performance hit of a database read beforehand?
All this said, I'd still be super happy just to see any of this being made usable soon; I'm being picky when I should really be grateful!
from firebase-functions.
@laurenzlong Re #1, of course! My oversight.
For #2, if it should indeed be (the ES2015 object literal property value shorthand syntax-using) {auth, {admin: false}}
(as opposed to {auth: {admin: false}}
), how should I instantiate or mock the auth variable?
from firebase-functions.
@laurenzlong I would love to allow by CLI parameter to choose production/testing database.
from firebase-functions.
Hi @laurenzlong - I have looked at the links and stackoverflow and can't get firebase functions debugging in VS code to work. Do you have any new links to get more information/help? It feels like a huge step backwards to debug with console.log π
from firebase-functions.
@dauledk We currently don't officially support IDE debugging. This is on our radar, but we haven't had a chance to make it work.
from firebase-functions.
@laurenzlong Would there be a way to hook up the emulator for functions to firebase-server?
from firebase-functions.
hi @laurenzlong I have a noob question. I wrote a firebase function which are triggered by my application directly not by http request. Can we test it by running function locally? i managed to run function locally but I couldn't find a way to trigger the function. Can you guide me a bit? thx in advance.
from firebase-functions.
@KendoJaaa Please see https://firebase.google.com/docs/functions/local-emulator
from firebase-functions.
@laurenzlong thx for your response. actually I've read that page, but couldn't make it.
I want elaborate more so you understand me better
this is what I did in my app. (calling function directly from the app) see the link below
https://firebase.google.com/docs/functions/callable
and I run the function locally using Cloud Functions shell according to this link
https://firebase.google.com/docs/functions/local-emulator
I assume that calling function directly from the app is actually HTTP request behind the scene.
The point is I don't know how the shell command looks like in order to trigger the function. I couldn't find the example in the page
from firebase-functions.
Thx ;)
from firebase-functions.
Hi can I hijack this thread to ask if it is possible to pass authentication to https callabale when testing from firebase shell?
if I do myCallableFunction.post().json({"data": {"test": "test"}})
My context.auth
is empty, so I tried myCallableFunction.post('', {"auth": {"uid": "abc"}}).json({"data": {"test": "test"}})
but got Error: no auth mechanism defined
. Is there a way to pass auth when testing callables locally?
from firebase-functions.
Related Issues (20)
- How to deploy function with latest secrets at RUNTIME? HOT 2
- DocumentOptions do not allow parameterized configuration values HOT 2
- Various Firebase functions started reporting crash: Maximum call stack size exceeded HOT 10
- regression with firebase-functions-test wrapping a v1 scheduled function HOT 2
- Please move `node-fetch` as a `devDependency` HOT 1
- `getDownloadURL` function fails in emulator mode if storage rules are not allowed HOT 3
- Consider exporting `SecretParam` type HOT 3
- CORS error when calling v2 functions using onCall HOT 3
- CallableOptions doesn't accept BooleanParam which is accepted by HttpsOptions HOT 2
- Structured logging error context not being serialized HOT 3
- Don't verify auth token on public endpoints HOT 5
- Firebase Blocking Auth Functions Run Incorrectly on Failed Signup HOT 2
- Module '"firebase-functions/v1"' has no exported member 'onInit'. HOT 5
- Single CORS origin ignored for `onCall` HOT 1
- Auth onCreate trigger doesn't trigger in emulators with magic link sign in flow HOT 2
- Firebase Functions v2 missing labels for documentOnwritten HOT 3
- defineSecret creates a list of values in Secret Manager HOT 5
- Firestore triggers have authType unknown when I make updates to documents from the firebase console HOT 2
- [logger]: express deprecated req.host: Use req.hostname instead HOT 1
- Any Document Trigger Failing for nested triggers HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from firebase-functions.