{"id":16426720,"url":"https://github.com/pulyaevskiy/firebase-functions-interop","last_synced_at":"2025-04-07T06:07:45.502Z","repository":{"id":48388943,"uuid":"94506170","full_name":"pulyaevskiy/firebase-functions-interop","owner":"pulyaevskiy","description":"Firebase Functions Interop Library for Dart.","archived":false,"fork":false,"pushed_at":"2023-10-19T16:28:15.000Z","size":249,"stargazers_count":191,"open_issues_count":22,"forks_count":53,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-31T04:07:23.290Z","etag":null,"topics":["dart","dart2js","firebase-functions","nodejs"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pulyaevskiy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-16T04:50:22.000Z","updated_at":"2025-01-13T10:42:19.000Z","dependencies_parsed_at":"2024-06-21T07:30:21.883Z","dependency_job_id":"0e6eb5e4-ba46-4022-917f-816c31c92157","html_url":"https://github.com/pulyaevskiy/firebase-functions-interop","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulyaevskiy%2Ffirebase-functions-interop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulyaevskiy%2Ffirebase-functions-interop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulyaevskiy%2Ffirebase-functions-interop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulyaevskiy%2Ffirebase-functions-interop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pulyaevskiy","download_url":"https://codeload.github.com/pulyaevskiy/firebase-functions-interop/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247601448,"owners_count":20964864,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","dart2js","firebase-functions","nodejs"],"created_at":"2024-10-11T08:10:03.988Z","updated_at":"2025-04-07T06:07:45.480Z","avatar_url":"https://github.com/pulyaevskiy.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://img.shields.io/travis-ci/pulyaevskiy/firebase-functions-interop.svg?branch=master\u0026style=flat-square)](https://travis-ci.org/pulyaevskiy/firebase-functions-interop) [![Pub](https://img.shields.io/pub/v/firebase_functions_interop.svg?style=flat-square)](https://pub.dartlang.org/packages/firebase_functions_interop) [![Gitter](https://img.shields.io/badge/chat-on%20gitter-c73061.svg?style=flat-square)](https://gitter.im/pulyaevskiy/firebase-functions-interop)\n\nWrite Firebase Cloud functions in Dart, run in Node.js. This is an early\ndevelopment preview, open-source project.\n\n\u003e Using `1.0.0-dev.*` version? See [UPGRADING.md][] for details on breaking changes and\n\u003e upgrade instructions.\n\n[UPGRADING.md]: https://github.com/pulyaevskiy/firebase-functions-interop/blob/master/UPGRADING.md\n\n## What is this?\n\n`firebase_functions_interop` provides interoperability layer for\nFirebase Functions Node.js SDK. Firebase functions written in Dart\nusing this library must be compiled to JavaScript and run in Node.js.\nLuckily, a lot of interoperability details are handled by this library\nand a collections of tools from Dart SDK.\n\nHere is a minimalistic \"Hello world\" example of a HTTPS cloud function:\n\n```dart\nimport 'package:firebase_functions_interop/firebase_functions_interop.dart';\n\nvoid main() {\n  functions['helloWorld'] = functions.https.onRequest(helloWorld);\n}\n\nvoid helloWorld(ExpressHttpRequest request) {\n  request.response.writeln('Hello world');\n  request.response.close();\n}\n```\n\n## Status\n\nVersion 1.0.0 is considered stable though not feature complete.\nBelow is status report of already implemented functionality by namespace:\n\n- [x] functions\n- [x] functions.config\n- [ ] functions.analytics\n- [x] functions.auth\n- [x] functions.firestore :fire:\n- [x] functions.database\n- [x] functions.https\n- [x] functions.pubsub\n- [x] functions.storage\n- [ ] functions.remoteConfig\n\n## Usage\n\n\u003e Make sure you have Firebase CLI installed as well as a Firebase account\n\u003e and a test app.\n\u003e\n\u003e See [Getting started](https://firebase.google.com/docs/functions/get-started)\n\u003e for more details.\n\n### 1. Create Initial Project\n\n```bash\n$ mkdir myproject\n$ cd myproject\n$ firebase init functions\n```\n\nThis creates `functions` subdirectory in your project's root which contains\nstandard Node.js package structure with `package.json` and `index.js` files.\n\n### 2. Initialize Dart Project\n\nGo to `functions` sub-folder and add a `pubspec.yaml` with following contents:\n\n```yaml\nname: myproject_functions\ndescription: My project functions\nversion: 0.0.1\n\nenvironment:\n  sdk: '\u003e=2.0.0-dev \u003c3.0.0'\n\ndependencies:\n  # Firebase Functions bindings\n  firebase_functions_interop: ^1.0.0\n\ndev_dependencies:\n  # Needed to compile Dart to valid Node.js module.\n  build_runner: ^1.0.0\n  build_node_compilers: ^0.2.0\n```\n\nThen run `pub get` to install dependencies.\n\n### 3 Write a Basic Function\n\nCreate `functions/node/index.dart` and type in something like this:\n\n```dart\nimport 'package:firebase_functions_interop/firebase_functions_interop.dart';\n\nvoid main() {\n  functions['helloWorld'] = functions.https.onRequest(helloWorld);\n}\n\nvoid helloWorld(ExpressHttpRequest request) {\n  request.response.writeln('Hello world');\n  request.response.close();\n}\n```\n\nCopy-pasting also works.\n\n### 4. Build your Function(s)\n\nVersion `1.0.0` of this library depends on Dart 2 and the new `build_runner`\npackage. Integration with dart2js and DDC compilers is provided by\n`build_node_compilers` package which should already be in `dev_dependencies`\nin `pubspec.yaml` (see step 2).\n\nCreate `functions/build.yaml` file with following contents:\n\n```yaml\ntargets:\n  $default:\n    sources:\n      - \"node/**\"\n      - \"lib/**\"\n    builders:\n      build_node_compilers|entrypoint:\n        generate_for:\n        - node/**\n        options:\n          compiler: dart2js\n          # List any dart2js specific args here, or omit it.\n          dart2js_args:\n          - --minify\n```\n\n\u003e By default `build_runner` compiles with DDC which is not supported by this\n\u003e library at this point. Above configuration makes it compile Dart with dart2js.\n\nTo build run following:\n\n```bash\n$ cd functions\n$ pub run build_runner build --output=build\n```\n\n### 5. Deploy\n\nThe result of `pub run` is located in `functions/build/node/index.dart.js`.\n\nIn your `functions/package.json`, set the `main` field to point to this file:\n\n```json\n{\n    \"...\": \"...\",\n    \"main\": \"build/node/index.dart.js\"\n}\n```\n\nAlternatively, you can replace the default `index.js` with the built version:\n\n```bash\n$ cp functions/build/node/index.dart.js functions/index.js\n```\n\nDeploy using Firebase CLI:\n\n```bash\n$ firebase deploy --only functions\n```\n\n### 6. Test it\n\nYou can navigate to the new HTTPS function's URL printed out by the deploy command.\nFor the Realtime Database function, login to the Firebase Console and try\nchanging values under `/messages/{randomValue}/original`.\n\n### 7. Scripts (optional)\n\nYou can use NPM scripts to simplify the work-flow of serving and deploying functions.\n\nUpdate your `functions/package.json` to be like so:\n\n```json\n{\n\t\"...\": \"...\",\n    \"scripts\": {\n         \"build\": \"pub run build_runner build --output=build\",\n         \"watch\": \"pub run build_runner watch --output=build\",\n\n        \"preserve\": \"npm run build\",\n        \"serve\": \"firebase serve --only functions\",\n\n        \"predeploy\": \"npm run build\",\n        \"deploy\": \"firebase deploy --only functions\",\n\n        \"preshell\": \"npm run build\",\n        \"shell\": \"firebase experimental:functions:shell\",\n\n        \"...\": \"...\"\n    }\n}\n```\n\n## Examples\n\n\n### HTTPS Function\n\n```dart\nimport 'package:firebase_functions_interop/firebase_functions_interop.dart';\n\nvoid main() {\n  functions['helloWorld'] = functions.https.onRequest(helloWorld);\n}\n\nvoid helloWorld(ExpressHttpRequest request) {\n  request.response.writeln('Hello world');\n  request.response.close();\n}\n```\n\n### Realtime Database Function\n\n```dart\nvoid main() {\n  functions['makeUppercase'] = functions.database\n      .ref('/messages/{messageId}/original')\n      .onWrite(makeUppercase);\n}\n\nFutureOr\u003cvoid\u003e makeUppercase(\n    Change\u003cDataSnapshot\u003cString\u003e\u003e change, EventContext context) {\n  final DataSnapshot\u003cString\u003e snapshot = change.after;\n  var original = snapshot.val();\n  var pushId = context.params['testId'];\n  print('Uppercasing $original');\n  var uppercase = pushId.toString() + ': ' + original.toUpperCase();\n  return snapshot.ref.parent.child('uppercase').setValue(uppercase);\n}\n```\n\n### Firestore Function\n\n```dart\nvoid main() {\n  functions['makeNamesUppercase'] = functions.firestore\n      .document('/users/{userId}').onWrite(makeNamesUppercase)\n}\n\nFutureOr\u003cvoid\u003e makeNamesUppercase(Change\u003cDocumentSnapshot\u003e change, EventContext context) {\n  // Since this is an update of the same document we must guard against\n  // infinite cycle of this function writing, reading and writing again.\n  final snapshot = change.after;\n  if (snapshot.data.getString(\"uppercasedName\") == null) {\n    var original = snapshot.data.getString(\"name\");\n    print('Uppercasing $original');\n\n    UpdateData newData = new UpdateData();\n    newData.setString(\"uppercasedName\", original.toUpperCase());\n\n    return snapshot.reference.updateData(newData);\n  }\n  return null;\n}\n```\n\n### Pubsub Functions\n\n```dart\nvoid main() {\n  functions['logPubsub'] = functions.pubsub.topic('my-topic').onPublish(logPubsub);\n}\n\nvoid logPubsub(Message message, EventContext context) {\n  print(message.json[\"name\"]);\n}\n```\n\n### Storage Functions\n\n```dart\nvoid main() {\n  functions['logStorage'] = functions.storage.object().onChange(logStorage);\n}\n\nvoid logStorage(ObjectMetadata data, EventContext context) {\n  print(data.name);\n}\n```\n\n### Auth Functions\n\n```dart\nvoid main() {\n  functions['logAuth'] = functions.auth.user().onCreate(logAuth);\n}\n\nvoid logAuth(UserRecord data, EventContext context) {\n  print(data.email);\n}\n```\n\n## Configuration\n\nFirebase SDK provides a way to set and access environment variables from\nyour Firebase functions.\n\nEnvironment variables are set using Firebase CLI, e.g.:\n\n```bash\nfirebase functions:config:set some_service.api_key=\"secret\" some_service.url=\"https://api.example.com\"\n```\n\nFor more details see https://firebase.google.com/docs/functions/config-env.\n\nTo read these values in a Firebase function use `functions.config`.\n\nBelow example also uses [node_http][] package which provides a HTTP client\npowered by Node.js I/O.\n\n[node_http]: https://pub.dartlang.org/packages/node_http\n\n```dart\nimport 'package:firebase_functions_interop/firebase_functions_interop.dart';\nimport 'package:node_http/node_http.dart' as http;\n\nvoid main() {\n  functions['helloWorld'] = functions.https.onRequest(helloWorld);\n}\n\nvoid helloWorld(ExpressHttpRequest request) async {\n  /// fetch env configuration\n  final config = functions.config;\n  final String serviceKey = config.get('someservice.key');\n  final String serviceUrl = config.get('someservice.url');\n  /// `http.get()` function is exposed by the `node_http` package.\n  var response = await http.get(\"$serviceUrl?apiKey=$serviceKey\");\n  // do something with the response, e.g. forward response body to the client:\n  request.response.write(response.body);\n  request.response.close();\n}\n```\n\n## HTTPS Functions Details\n\nFirebase uses the Express.js web framework for HTTPS functions with `body-parser`\nmiddleware enabled by default ([documentation](https://firebase.google.com/docs/functions/http-events#read_values_from_the_request)).\n\nThe `ExpressHttpRequest` exposed by this library extends standard `dart:io`\n`HttpRequest` interface, which means it is also a stream of bytes. However\nif `body-parser` middleware already decoded request body then listening for\ndata on the request would hang since it's already been consumed. Use\n`ExpressHttpRequest.body` field to get decoded request body in this case.\n\n\n## Features and Bugs\n\nPlease file feature requests and bugs at the [issue tracker](https://github.com/pulyaevskiy/firebase-functions-interop/issues/new).\n\nSee [the development file](DEVELOPMENT.md) for instructions on running the test suite.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpulyaevskiy%2Ffirebase-functions-interop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpulyaevskiy%2Ffirebase-functions-interop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpulyaevskiy%2Ffirebase-functions-interop/lists"}