GoogleCloudPlatform / functions-framework-dart

FaaS (Function as a service) framework for writing portable Dart functions
https://pub.dev/packages/functions_framework
Apache License 2.0
537 stars 54 forks source link

Questions re: firebase integration #238

Closed jimmyff closed 1 year ago

jimmyff commented 3 years ago

Hi, This looks great, I'm currently using firebase_functions_interop on 3 production projects but as it seems that project has become unmaintained I need an alternative.

I don't believe firebase functions allows for custom containers yet so I'm unclear how I could use this project in these situations:

  1. Firestore hooks, onCreate, onDelete etc
  2. Callable requests (https), my flutter apps sometimes need an instance response from a backend (so pub sub is not applicable) and in these situations I use cloud_functions.call()
  3. Cloud storage hooks: I assume I can do this via pub sub?

Thanks

mtwichel commented 3 years ago

Hey! I'm not the maintainer, just someone trying to solve similar problems. I agree these would be awesome to have, but for now I've found some nice workarounds you could try:

  1. and 3. I've written super lightweight cloud functions in nodejs that listen to Firestore or Cloud Storage and relay their payload to a pubsub topic. You can then respond to the pubsub messages using your Dart function using Eventarc and setting a pubsub trigger

  2. As I understand, the advantage to using callable functions is that it validates the auth token from Firebase auth and parses your json payload into an object.

    • For the first problem, you can validate the tokens pretty easily; you just have to include the token in a header when you make a request (you can get the token from all the client libraries) and validate it on the back end. In fact, I just made a small package for validating the tokens (https://pub.dev/packages/validate_firebase_auth). It's still very new but should work for validating the JWTs from Firebase Auth.
    • For the second, the Functions Framework can already serialize and deserialize dart objects to json as long as you include a .toJson in your response object and a .fromJson in your request object. Example here
    • The only issue is if you write a json serialized function as of now, you can't get to the headers so you'll probably have to do a standard http function for now if you need both functionalities.
jimmyff commented 3 years ago

Thanks for the ideals @mtwichel, I don't suppose you have an example of your nodejs function?

I'm guessing we need to wait for Dart to be added as a Runtime option in GCP Cloud Functions for this to be properly resolved. At that point we won't need to use Cloud Run either.

Thanks

jimmyff commented 3 years ago

Also just spotted this discussion topic which is talking about EventArc, this looks like a great solution for connecting firestore & storage to your functions_framework project.

mtwichel commented 3 years ago

@jimmyff

Thanks for the ideals @mtwichel, I don't suppose you have an example of your nodejs function?

Something like this?

const functions = require('firebase-functions');
const {PubSub} = require('@google-cloud/pubsub');

const pubSubClient = new PubSub();

exports.myFunction = functions.firestore
  .document('my-collection/{docId}')
  .onWrite((change, context) => { 
    const dataBuffer = Buffer.from(change);
    const messageId = await pubSubClient.topic(topicName).publish(dataBuffer);
 });

Also just spotted this discussion topic which is talking about EventArc, this looks like a great solution for connecting firestore & storage to your functions_framework project.

Cloud Run – Dart Backend – Google Cloud Platform

Unfortunately, I don’t think that use case is supported yet because EventArc doesn’t have events that you can hook into from changes to documents in Firestore or changes in storage :/ It does have a Cloud Firestore section but it only has admin events in the logs (like deploying indexes). In fact, it looks like the only thing that isn’t just reacting to log evens is pubsub, so using the above function you would have to set up the EventArc trigger to listen to the same pubsub topic you’re publishing to.

Patrick386 commented 2 years ago

One year has already passed. Do you have any support plans for firebase? I would like to hear from the manager.

kevmoo commented 2 years ago

Hey @Patrick386 – we're super excited to get functions going, but it's a lot of work across a few teams.

We're super excited to have an offering is this space, but we won't having anything in the near future.

Patrick386 commented 2 years ago

Hey @Patrick386 – we're super excited to get functions going, but it's a lot of work across a few teams.

We're super excited to have an offering is this space, but we won't having anything in the near future.

Thanks for letting me know. We are waiting for good news.

jimmyff commented 2 years ago

Thanks for letting me know. We are waiting for good news.

Hey @Patrick386, If you're willing to have a slightly more complex setup you can do what you need right now using this package & cloud-run (using Google Cloud Platform). You can even validate the Firebase authentication JWT tokens to make sure the user is logged in and grab their claims too. As a bonus you then have the benefit of being able to stick all your functions/cloud-run instances behind a global load balancer and do fancy things like caching and security.

jimmyff commented 2 years ago

Unfortunately, I don’t think that use case is supported yet because EventArc doesn’t have events that you can hook into from changes to documents in Firestore or changes in storage :/ It does have a Cloud Firestore section but it only has admin events in the logs (like deploying indexes). In fact, it looks like the only thing that isn’t just reacting to log evens is pubsub, so using the above function you would have to set up the EventArc trigger to listen to the same pubsub topic you’re publishing to.

Hey @mtwichel did you have any luck with this? I noticed yesterday that there were Event Arc triggers now although I've been unable to get them working. I've been to Audit config and I've enabled Firestore write audit logs, but for some reason my Cloud run instance doesn't get invoked.

diezep commented 1 year ago

Hi @jimmyff, did you found a solution on this topic? I'm facing the same issue.

Hi, This looks great, I'm currently using firebase_functions_interop on 3 production projects but as it seems that project has become unmaintained I need an alternative.

I don't believe firebase functions allows for custom containers yet so I'm unclear how I could use this project in these situations:

  1. Firestore hooks, onCreate, onDelete etc
  2. Callable requests (https), my flutter apps sometimes need an instance response from a backend (so pub sub is not applicable) and in these situations I use cloud_functions.call()
  3. Cloud storage hooks: I assume I can do this via pub sub?

Thanks

jimmyff commented 1 year ago

Hey @diezep,

I use package:functions_framework deployed to Cloud Run succesfully for almost all my requirements. I have about 60 Cloud Run instances in production and it works great. I invoke them as https endpoints or as endpoints for Google cloud Pub Sub subscriptions.

One of the magic black boxes you get with Firebase functions is the authentication, however the cloud run approach you have to do that yourself: I send the Firebase Auth's JWT to my Cloud Run's endpoint which is verifies to be valid using package:jose and package:x509 (...don't forget to check the claims.issuer is actually your app!).

I communicate with all the firebase services via package:googleapis. The only none dart cloud function is one that utlises the firebase_admin SDK (which I use to set claims against the Firebase User objects) I have a Google Cloud cloud function setup for that which I is written in Go. Hopefully at some point I can replace that when the admin sdk gets a dart package (maybe that's already happened since I last checked...).

Re: Triggers / EventArc: I never really got the EventArc stuff working correctly. Last time I looked at it (months ago) I did manage to get some general EventArc triggers invoking my CloudRun endpoints but I was unclear how to specify specific collections, I think there was a filter field but I had no idea what data/format it expected. I'm sure with some more fiddling I would have figured it out as it did seem to be working. The problem I had was the documentation hadn't caught up with the product development and I seemed to be the only person outside of Google trying to use this (based on lack of questions or discussion online / stack overflow). My solution was to work around the lack of firestore triggers. I use Google cloud Pub Sub which goes someway to fulfilling my requirements.

I'll close this issue now as integration with event arc and firebase are out of the scope of this project.

diezep commented 1 year ago

Thank you for respond @jimmyff, I'm trying to catch the trigger with Eventarc (still trying) but i will consider use pubsub instead. ~For every endpoint that I want to expose or invoke do I have to have an instance in google cloud run? If that's the case, how do you manage the code project? I'm trying to write different cloud functions in the same file as NodeJS project with the SDK, is that possible? I appreciate your help and I apologize if I'm asking things that are basic, I'm not too familiar with this topic.~ I just saw #241. Thanks.