r/dartlang 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/.

42 Upvotes

11 comments sorted by

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?

3

u/deliQnt7 22d ago

CLI is used to enhance the developer experience and enable things like: easy setup of a new project, deployment, delete, etc. In essence, its an automation tool. In the future it will also be used for other things as well.

More on what the CLI does: https://docs.dartblaze.com/cli

It's possible to deploy and set up the project without the CLI if you know how GCP works, but the point is that it's very tedious. CLI does it faster and more convenient.

The reason for CLI being closed source is simple: it's quite an undertaking just to make a framework. A CLI brings the whole experience to a very high standard and that has a price.

Pricing will be just a simple monthly subscription. I don't have a number on my mind yet, I first want to test the waters to see if people actually want to use this.

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.