firebase_node 0.1.3+1
firebase_node: ^0.1.3+1 copied to clipboard

Wrapper for firebase functions and firebase admin to run in Node.js.

Pub Version Gitter

Wrapper for firebase functions and firebase admin to run in Node.js based on package:firebase and package:firebase_functions_interop.

Note: This package is in active development and may contains bugs. Contribution is highly appreciated.

Usage #

create project #

mkdir example
cd example
firebase init functions
mkdir functions/node

example/functions/node/main.dart #

import 'package:firebase_node/admin.dart';
import 'package:firebase_node/functions.dart';

void main() {
  functions['onCreateUser'] = functions.auth.user().onCreate(onCreateUser);

  functions['onDeleteUser'] = functions.auth.user().onDelete(onDeleteUser);

  functions['storageFunctions'] =
      functions.storage.bucket('my-bucket').object().onFinalize(onFinalize);

  // non-Future function
  functions['documentUpdate'] =
      functions.firestore.document('my-document').onUpdate((change, context) {
    print(context.auth.uid);
    return 0;
  });
}

final app = initializeApp();

//Future function must have literal
Future<int> onDeleteUser(UserRecord user, EventContext context) async {
  final ref = app.firestore().collection('userdata').doc(user.uid);
  await ref.delete();
  return 0; //Every function must return value so that Firebase functions know when the function end.
}

Future<int> onFinalize(ObjectMetadata metadata, EventContext context) async {
  final ref = app.firestore().collection('tracker').doc('my-bucket');
  final fieldsAndValues = [
    FieldPath('file', metadata.name),
    metadata.size,
    'file_count',
    FieldValue.increment(1),
  ];
  await ref.update(fieldsAndValues: fieldsAndValues);
  return 0;
}

Future<int> onCreateUser(UserRecord user, EventContext context) async {
  final ref = app.firestore().collection('userdata').doc(user.uid);
  final data = {
    'name': user.displayName,
    'email': user.email,
    'timestamp': FieldValue.serverTimestamp(),
  };
  await ref.set(data);
  return 0;
}

example/functions/build.yaml #

targets:
  $default:
    builders:
      firebase_node|nodejs_builder:
        enabled: true
        options:
          # node_modules is optional to require any node modules
          node_modules:
            # This wil output
            # 'const someModule = require("module-name")'
            # 'self.someModule = someModule'
            # So if you have custom js interop you can use node module @JS('someModule')
            someModule: module-name
          dart2js_args:
            - -O1

example/functions/pubspec.yaml #

name: firebase_node_example

environment:
  sdk: '>=2.8.1 <3.0.0'

dependencies:
  firebase_node:

dev_dependencies:
  build_runner:

example/functions/package.json #

{
  "name": "firebase_node_example",
  "engines": {
    "node": "10"
  },
  "main": "build/node/main.dart.node.js",
  "dependencies": {
    "firebase-admin": "^8.10.0",
    "firebase-functions": "^3.6.1"
  }
}

example/firebase.json #

{
  "functions": {
    "ignore": ["node_modules", ".dart_tool", "packages"]
  }
}

compile #

cd functions
pub run build_runner build --output build
firebase deploy

Project Structure #

example/
├─firebase.json
└─functions/
  ├─lib/
  ├─node/
  │ └─main.dart
  ├─package.json
  ├─build.yaml
  └─pubspec.yaml

Progress #

firebase_node.admin #

  • [x] app
  • [x] auth
  • [x] credential
  • [x] database
  • [x] firestore
  • [x] instance id
  • [x] machine learning
  • [x] messaging
  • [x] project management
  • [x] remote config
  • [x] security rules
  • [ ] storage (partial complete)

firebase_node.functions #

  • [x] analytics
  • [x] auth
  • [x] crashlytics
  • [x] database
  • [x] firestore
  • [x] https
  • [x] pubsub
  • [x] remote config
  • [x] storage
  • [x] test lab

Features and bugs #

Please file feature requests and bugs at the issue tracker.