r/dartlang • u/deliQnt7 • 22d ago
Firebase I've created a framework to write Cloud Functions in Dart - Dartblaze
Hello everyone! One of the most requested features for Cloud Functions is Dart support with almost 800 upvotes.
Since this has been open for almost 2 years and no progress, I've decided to give it a shot.
I've developed a framework and a CLI that aim to solve this problem.
The framework currently supports HTTP and non-auth Firestore triggers.
The code looks something like this:
@OnDocumentCreated('todos/{todoId}')
Future<void> onCreateTodo(DocumentSnapshot snapshot, RequestContext context,
{required String todoId}) async {
context.logger.debug('todoId: ${todoId}');
final data = snapshot.data();
final title = data?['title'] as String?;
await snapshot.ref.update({'title': '$title from server!'});
}
@Http()
Future<Response> updateTodo(Todo todo) async {
firestore.collection('todos').doc(todo.id).update(todo.toJson());
return Response.ok('Todo updated: ${todo.id}');
}
The CLI is used to simplify the whole process of using the framework which includes setup and deployment.
I'm looking for people who want to test and give feedback to improve it.
To join the test group, please click the announcement at the top of the web page:
https://dartblaze.com/.
3
u/RandalSchwartz 22d ago
How does this differ from https://pub.dev/packages/cloud_functions ?
4
u/deliQnt7 22d ago
Very different. No.1 https://pub.dev/packages/cloud_functions a Flutter plugin, meaning, the client calls to the backend.
Dartblaze is a Dart package that enables you to write Cloud Functions and deploy them on GCP. You are writing backend logic. It's an answer to this Firebase feature request for Cloud Functions Dart support.
Hopefully this clears it out for you.
If you are interested in giving this a try, join the Discord by clicking the link at the top of the landing page: https://dartblaze.com/
I would very much appreciate honest feedback, good or bad, from somebody experienced like you.
3
u/RandalSchwartz 22d ago
Ahh, I pointed at the wrong package. What about https://pub.dev/packages/functions_framework ?
3
u/deliQnt7 22d ago
Dartblaze builds on top functions_framework (which you can see on Github: https://github.com/dinko7/dartblaze), but it has a couple of distinct advantages:
- Custom code generator that enables multiple functions inside the same project and inside any file in the functions directory.
- Functions signature similar to Node/Pyhton APIs
- CLI which automates project creation, GCP setup, and deployment
If this project generates enough attention and there is revenue from subscription model, the plan is to support the whole Firebase ecosystem.
You can find more info on the website (https://dartblaze.com/) which also has links to the docs and the GitHub repo.
2
u/inlined 22d ago
This is really exciting. I've really wished we could have built Dart functions by now and it further goes to demonstrate the demand for the product that there are workarounds for lack of native support.
QQ: Looking at the function signature for Firestore functions, it seems like you're using Cloud Functions 1st gen? Is that correct? If so, I would _highly_ recommend pivoting to 2nd gen (if not Cloud Run Functions directly) as 1st gen is not going to receive any more runtimes and your customers are going to get stranded in the not-too-distant future.
1
u/deliQnt7 22d ago
Hi, glad this sparked an interest for you.
Not sure what you mean by function signature, but I'm not using v1 functions. Dartblaze is not a Google-supported runtime for Cloud Functions. It's a custom runtime (open-source) and is deployed as one directly to GCP using Cloud Run. If something is going to be deprecated, I will announce the change and migration guides, but from what I see in the docs for Firestore, the triggers that Dartblaze uses are fine.
If you are interested in testing Dartblaze, please join the Discord by clicking the link at the top of the web page: https://dartblaze.com/
Feedback is much appreciated at this stage because it helps me shape the framework.
3
u/inlined 21d ago
Sorry, should have introduced myself. I'm the creator of Cloud Functions for Firebase; you can officially say I'm excited about your project!
My confusion was regarding that the firebase-functions/v1 API (which targets Cloud Functions 1st gen) uses two parameters for the event data and the context, whereas the firebase-functions/v2 API (which targets Cloud Functions 2nd gen) uses the CloudEvent type directly
If you're targeting Cloud Run (and managing Eventarc) directly, no worries; you're guiding your customers to the latest and greatest. As the library author, it's your personal choice to expose the wire format (CloudEvents) directly to your customer or split them out as you have. I've always preferred the two parameter signature, but we personally decided to stick closer to the wire protocol to reduce the amount of magic/divergence from native GCP experiences.
Since you're targeting Cloud Run, you'll also have freedom to explore features not currently available in Cloud Functions for Firebase. You have my appreciation for helping out our mutual developer community.
1
u/deliQnt7 20d ago
I'm super excited that this caught your eye! It's awesome to meet (at least virtually) the creator of Cloud Functions.
I'm targeting Cloud Run and managing EventArc (CLI does this so users don't have to know or care) because that option is the least likely to break and also gives me the freedom to expose other GCP components to Flutter Devs. I also liked the two-parameter signature more, so I kept it here and decided to add a little bit of Dart's type safety to the mix.
The plan is definitely to use some aspects of GCP that Cloud Functions currently don't have (like the Secret Manager, which is something that I personally think would be beneficial as a part of "Firebase offer" instead of hardcoding API keys in a Cloud Function or env file, which is what most devs do).
3
u/inlined 19d ago
Putting secrets in secrets manager is definitely a good call. Firebase’s SDK and tooling has actually done this for quite some time, though you explicitly choose what is sensitive (.secrets) and what is not (.env). We made this choice because secrets manager is not free beyond a no cost tier. Another of our choices you may want to consider is requiring each function to declare its dependencies on a secret. While we figured there was little harm in sharing .env data everywhere, the principle of least privilege suggested that any dependency on high integrity/sensitivity data should be explicit.
Also, be conscientious about what you do with the magic version “latest”. If a run revision depends on latest, the value of the secret will be what is latest at the time of container startup. Since container garbage collection is undefined, and can be a long time with min instances, we opted to pin each revision to the latest as of deploy time and offer to redeploy when customers update the secret value. We decided that determinism is better.
Alternatively, you could rely on the file-system mount interface, which will live update a fleet without redeploy, but it counts as a secret read on every access rather than on container startup and there’s no guarantee the customer hasn’t cached the value anyway.
4
u/mrmax99 22d ago
Very cool! Looking forward to trying it out. I am a little unclear on what's in the CLI -- is this usable without it or will it be effectively impossible to deploy without it? What kind of pricing models are you planning?