From c99dacdec08e31265b1b5b058bc8e7f527c9326f Mon Sep 17 00:00:00 2001 From: Lejard Hadrien Date: Sun, 17 Feb 2019 20:37:46 +0100 Subject: [PATCH] support Transaction api --- crossfire/lib/src/crossfire_base.dart | 18 +++++++ crossfire_flutter/lib/crossfire_flutter.dart | 51 ++++++++++++++++++ crossfire_web/lib/crossfire_web.dart | 55 +++++++++++++++++++- 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/crossfire/lib/src/crossfire_base.dart b/crossfire/lib/src/crossfire_base.dart index 06fb224..ecbf236 100644 --- a/crossfire/lib/src/crossfire_base.dart +++ b/crossfire/lib/src/crossfire_base.dart @@ -13,6 +13,7 @@ abstract class Firebase { Future getStorage(String path); bool get isConnected; Stream get onConnectivityUpdated; + Future runTransaction(TransactionRunner updateFunction); } abstract class FirebaseDocument { @@ -103,3 +104,20 @@ enum FireDocumentChangeType { /// longer matches the query. removed, } + +typedef void TransactionRunner(FirebaseTransaction transaction); + +abstract class FirebaseTransaction { + Future delete(FirebaseDocumentReference documentRef); + Future getDocument(FirebaseDocumentReference documentRef); + Future setData( + FirebaseDocumentReference documentRef, + Map data, { + bool merge = false, + }); + Future update( + FirebaseDocumentReference documentRef, { + Map data, + List fieldsAndValues, + }); +} diff --git a/crossfire_flutter/lib/crossfire_flutter.dart b/crossfire_flutter/lib/crossfire_flutter.dart index b75d16f..82d710b 100644 --- a/crossfire_flutter/lib/crossfire_flutter.dart +++ b/crossfire_flutter/lib/crossfire_flutter.dart @@ -110,6 +110,12 @@ class FlutterFirebase implements Firebase { @override Stream get onConnectivityUpdated => _connectionChangedSink.stream; + + @override + Future runTransaction(TransactionRunner updateFunction) => + _firestore.runTransaction((t) { + updateFunction(FlutterFirebaseTransaction(t)); + }); } class FlutterFirebaseDocReference implements FirebaseDocumentReference { @@ -307,3 +313,48 @@ class FlutterStorageMetadata implements FirebaseStorageMetadata { String get contentType => _metadata.contentType; int get size => _metadata.sizeBytes; } + +class FlutterFirebaseTransaction implements FirebaseTransaction { + final Transaction _transaction; + + FlutterFirebaseTransaction(this._transaction); + + @override + Future delete( + FirebaseDocumentReference documentRef, + ) async { + final doc = documentRef as FlutterFirebaseDocReference; + await _transaction.delete(doc.ref); + return this; + } + + @override + Future getDocument( + FirebaseDocumentReference documentRef) async { + final doc = documentRef as FlutterFirebaseDocReference; + final snap = await _transaction.get(doc.ref); + return FlutterFirebaseDoc(snap); + } + + @override + Future setData( + FirebaseDocumentReference documentRef, + Map data, { + bool merge = false, + }) async { + final doc = documentRef as FlutterFirebaseDocReference; + await _transaction.set(doc.ref, data); + return this; + } + + @override + Future update( + FirebaseDocumentReference documentRef, { + Map data, + List fieldsAndValues, + }) async { + final doc = documentRef as FlutterFirebaseDocReference; + await _transaction.update(doc.ref, data); + return this; + } +} diff --git a/crossfire_web/lib/crossfire_web.dart b/crossfire_web/lib/crossfire_web.dart index f48c098..3728a89 100644 --- a/crossfire_web/lib/crossfire_web.dart +++ b/crossfire_web/lib/crossfire_web.dart @@ -37,13 +37,12 @@ class FirebaseWeb implements Firebase { if (usePersistence != null && usePersistence) { try { _store.enablePersistence(); - } catch(e) { + } catch (e) { // Support re-initializing with a different app. Enabling persistence // can throw an error if it has already been enabled once on the page. } } _storage = fb.storage(app); - } @override @@ -82,6 +81,10 @@ class FirebaseWeb implements Firebase { @override Stream get onConnectivityUpdated => _connectionChangeSink.stream; + + @override + Future runTransaction(TransactionRunner updateFunction) => _store + .runTransaction((t) => updateFunction(BrowserFirebaseTransaction(t))); } class BrowserFirebaseQuerySnapshot implements FirebaseQuerySnapshot { @@ -322,3 +325,51 @@ class BrowserFirebaseQuery extends FirebaseQuery { return new BrowserFirebaseQuery(q); } } + +class BrowserFirebaseTransaction implements FirebaseTransaction { + final Transaction _transaction; + + BrowserFirebaseTransaction(this._transaction); + + @override + Future delete( + FirebaseDocumentReference documentRef) async { + final doc = documentRef as BrowserFirebaseDocReference; + final t = _transaction.delete(doc._ref); + return BrowserFirebaseTransaction(t); + } + + @override + Future getDocument( + FirebaseDocumentReference documentRef) async { + final doc = documentRef as BrowserFirebaseDocReference; + final snap = await _transaction.get(doc._ref); + return BrowserDocumentSnapshot(snap); + } + + @override + Future setData( + FirebaseDocumentReference documentRef, + Map data, { + bool merge = false, + }) async { + final doc = documentRef as BrowserFirebaseDocReference; + final t = _transaction.set(doc._ref, data, SetOptions(merge: merge)); + return BrowserFirebaseTransaction(t); + } + + @override + Future update( + FirebaseDocumentReference documentRef, { + Map data, + List fieldsAndValues, + }) async { + final doc = documentRef as BrowserFirebaseDocReference; + final t = _transaction.update( + doc._ref, + data: data, + fieldsAndValues: fieldsAndValues, + ); + return BrowserFirebaseTransaction(t); + } +}