A pure Dart implementation of the Firebase client
Currently supports the following firebase services:
- Authentication
- Realtime database
- Cloud storage
As this is a pure dart implementation, it supports all platforms supported by dart, e.g. command line apps, web applications and flutter apps for android, ios, web, macos, windows and linux.
Getting started
Initialize firebase_dart with the directory where the library should store data that should persist between runs. The storage path can be null, in which case no data will be stored on disk.
FirebaseDart.setup(storagePath: 'path/to/persistent/storage');
In flutter apps, you can use the firebase_dart_flutter
library instead and initialize as follows. This will select an appropriate directory to store application data.
await FirebaseDartFlutter.setup();
The firebase code can also run in a separate isolate. This ensures that the main thread can be used for rendering tasks. To do this, simply set the isolated argument of the setup method to true. As isolates are not supported on web, this has no effect in a web environment.
Once the library is initialized, a firebase app can be created by calling:
var app = await Firebase.initializeApp(
options: FirebaseOptions.fromMap(json
.decode(File('example/firebase-config.json').readAsStringSync())));
Unit testing
Unlike the native firebase libraries, this library allows to write unit tests without an external firebase emulator.
To setup testing, import the testing implementation:
import 'package:firebase_dart/implementation/testing.dart';
and set it up:
await FirebaseTesting.setup();
Now, you can create an app and an associated backend:
var options = FirebaseOptions(
appId: 'my_app_id',
apiKey: 'apiKey',
projectId: 'my_project',
messagingSenderId: 'ignore',
authDomain: 'my_project.firebaseapp.com');
var app = await Firebase.initializeApp(options: options);
var backend = FirebaseTesting.getBackend(app.options);
The backend can be used to add test users and store test data. E.g.:
await backend.authBackend.storeUser(BackendUser('user1')
..createdAt = clock.now().millisecondsSinceEpoch.toString()
..lastLoginAt = clock.now().millisecondsSinceEpoch.toString()
..email = 'user@example.com'
..rawPassword = 'password'
..providerUserInfo = [
UserInfoProviderUserInfo()..providerId = 'password',
UserInfoProviderUserInfo()..providerId = 'google.com',
]);
Authentication
To get access to a Firebase Auth instance, call:
var auth = FirebaseAuth.instanceFor(app: app);
This implementation does not yet support all functionalities of the firebase authentication service. Here is a list of functionalities with the current support status:
method | supported? |
---|---|
FirebaseAuth.applyActionCode | ✅ |
FirebaseAuth.authStateChanges | ✅ |
FirebaseAuth.checkActionCode | ✅ |
FirebaseAuth.confirmPasswordReset | ✅ |
FirebaseAuth.createUserWithEmailAndPassword | ✅ |
FirebaseAuth.fetchSignInMethodsForEmail | ✅ |
FirebaseAuth.getRedirectResult | ❌ |
FirebaseAuth.idTokenChanges | ✅ |
FirebaseAuth.isSignInWithEmailLink | ✅ |
FirebaseAuth.sendPasswordResetEmail | ✅ |
FirebaseAuth.sendSignInLinkToEmail | ✅ |
FirebaseAuth.setLanguageCode | ✅ |
FirebaseAuth.setPersistence | ❌ |
FirebaseAuth.signInAnonymously | ✅ |
FirebaseAuth.signInWithCredential | ✅ |
FirebaseAuth.signInWithCustomToken | ✅ |
FirebaseAuth.signInWithEmailAndPassword | ✅ |
FirebaseAuth.signInWithEmailLink | ✅ |
FirebaseAuth.signInWithPhoneNumber | ✅ |
FirebaseAuth.signInWithPopup | ❌ |
FirebaseAuth.signInWithRedirect | ❌ |
FirebaseAuth.signInWithAuthProvider | ❌ |
FirebaseAuth.signOut | ✅ |
FirebaseAuth.userChanges | ✅ |
FirebaseAuth.verifyPasswordResetCode | ✅ |
FirebaseAuth.verifyPhoneNumber | ✅ |
User.delete | ✅ |
User.getIdToken | ✅ |
User.getIdTokenResult | ✅ |
User.linkWithCredential | ❌ |
User.linkWithPhoneNumber | ❌ |
User.reauthenticateWithCredential | ✅ |
User.reload | ✅ |
User.sendEmailVerification | ✅ |
User.unlink | ✅ |
User.updateEmail | ✅ |
User.updatePassword | ✅ |
User.updatePhoneNumber | ❌ |
User.updateProfile | ✅ |
User.verifyBeforeUpdateEmail | ❌ |
User.multiFactor | ✅ |
Multi-tenancy is currently not supported.
Realtime database
To get access to a Firebase Database instance, call:
var db = FirebaseDatabase(app: app);
The following methods are supported:
method | supported? |
---|---|
FirebaseDatabase.reference | ✅ |
FirebaseDatabase.goOnline | ✅ |
FirebaseDatabase.goOffline | ✅ |
FirebaseDatabase.purgeOutstandingWrites | ✅ |
FirebaseDatabase.setPersistenceEnabled | query results are stored, writes not |
FirebaseDatabase.setPersistenceCacheSizeBytes | ✅ |
DatabaseReference.* | ✅ |
Local database
Besides connecting to a remote firebase database, you can also create and work with a local in memory database. Use a database url with a mem
scheme for this:
var db = new FirebaseDatabase(app: app, databaseURL: 'mem://some.name/');
Query optimizations
The following optimizations are applied to queries to reduce the amount of network traffic:
- a query is not send to the server if other active queries already contain the result of this query
- if there are active queries that did not receive a result from the server yet, but might contain the result of this query, we wait for the result before we send a new query to the server
- multiple queries that limit their result to overlapping intervals are grouped together
Note: this feature is not included in official firebase clients. Because queries might be altered before sending them to the server, it is possible that queries are refused by the security rules which would otherwise not be refused. This should only happen with very particular security rules. This will be fixed in a future version of this library.
Cloud storage
To get access to a Firebase Storage instance, call:
var storage = FirebaseStorage.instanceFor(app: app);
The following methods are supported:
method | supported? |
---|---|
FirebaseStorage.ref | ✅ |
FirebaseStorage.refFromURL | ✅ |
FirebaseStorage.maxDownloadRetryTime | ❌ |
FirebaseStorage.maxOperationRetryTime | ❌ |
FirebaseStorage.maxUploadRetryTime | ❌ |
FirebaseStorage.setMaxDownloadRetryTime | ❌ |
FirebaseStorage.setMaxOperationRetryTime | ❌ |
FirebaseStorage.setMaxOperationRetryTime | ❌ |
Reference.delete | ✅ |
Reference.getData | ✅ |
Reference.getDownloadURL | ✅ |
Reference.getMetadata | ✅ |
Reference.list | ✅ |
Reference.listAll | ✅ |
Reference.putData | ✅ |
Reference.putString | ✅ |
Reference.updateMetadata | ✅ |
Features and bugs
Please file feature requests and bugs at the issue tracker.
Sponsor
Creating and maintaining this package takes a lot of time. If you like the result, please consider to :heart: sponsor. With your support, I will be able to further improve and support this project. Also, check out my other dart packages at pub.dev.
Many thanks to Tim Whiting for his support.