@@ -37,10 +37,9 @@ class BackendConnector extends PowerSyncBackendConnector {
3737 /// Get a token to authenticate against the PowerSync instance.
3838 @override
3939 Future <PowerSyncCredentials ?> fetchCredentials () async {
40-
4140 final user = FirebaseAuth .instance.currentUser;
42- if (user == null ) {
43- // Not logged in
41+ if (user == null ) {
42+ // Not logged in
4443 return null ;
4544 }
4645 final idToken = await user.getIdToken ();
@@ -64,14 +63,16 @@ class BackendConnector extends PowerSyncBackendConnector {
6463 // userId and expiresAt are for debugging purposes only
6564 final expiresAt = parsedBody['expiresAt' ] == null
6665 ? null
67- : DateTime .fromMillisecondsSinceEpoch (parsedBody['expiresAt' ]! * 1000 );
66+ : DateTime .fromMillisecondsSinceEpoch (
67+ parsedBody['expiresAt' ]! * 1000 );
6868 return PowerSyncCredentials (
6969 endpoint: parsedBody['powerSyncUrl' ],
7070 token: parsedBody['token' ],
7171 userId: parsedBody['userId' ],
7272 expiresAt: expiresAt);
7373 } else {
7474 print ('Request failed with status: ${response .statusCode }' );
75+ return null ;
7576 }
7677 }
7778
@@ -109,33 +110,44 @@ class BackendConnector extends PowerSyncBackendConnector {
109110
110111 var row = Map <String , dynamic >.of (op.opData! );
111112 row['id' ] = op.id;
112- Map <String , dynamic > data = {
113- "table" : op.table,
114- "data" : row
115- };
116-
113+ Map <String , dynamic > data = {"table" : op.table, "data" : row};
117114 if (op.op == UpdateType .put) {
118115 await upsert (data);
119116 } else if (op.op == UpdateType .patch) {
120117 await update (data);
121118 } else if (op.op == UpdateType .delete) {
119+ data = {
120+ "table" : op.table,
121+ "data" : {"id" : op.id}
122+ };
122123 await delete (data);
123124 }
124125 }
125126
126127 // All operations successful.
127128 await transaction.complete ();
129+ } on http.ClientException catch (e) {
130+ // Error may be retryable - e.g. network error or temporary server error.
131+ // Throwing an error here causes this call to be retried after a delay.
132+ log.warning ('Client exception' , e);
133+ rethrow ;
128134 } catch (e) {
129- log.severe ('Failed to update object $e ' );
130- transaction.complete ();
135+ /// Instead of blocking the queue with these errors,
136+ /// discard the (rest of the) transaction.
137+ ///
138+ /// Note that these errors typically indicate a bug in the application.
139+ /// If protecting against data loss is important, save the failing records
140+ /// elsewhere instead of discarding, and/or notify the user.
141+ log.severe ('Data upload error - discarding $lastOp ' , e);
142+ await transaction.complete ();
131143 }
132144 }
133145}
134146
135147/// Global reference to the database
136148late final PowerSyncDatabase db;
137149
138- upsert (data) async {
150+ upsert (data) async {
139151 var url = Uri .parse ("${AppConfig .backendUrl }/api/data" );
140152
141153 try {
@@ -154,10 +166,11 @@ upsert (data) async {
154166 }
155167 } catch (e) {
156168 log.severe ('Exception occurred: $e ' );
169+ rethrow ;
157170 }
158171}
159172
160- update (data) async {
173+ update (data) async {
161174 var url = Uri .parse ("${AppConfig .backendUrl }/api/data" );
162175
163176 try {
@@ -176,10 +189,11 @@ update (data) async {
176189 }
177190 } catch (e) {
178191 log.severe ('Exception occurred: $e ' );
192+ rethrow ;
179193 }
180194}
181195
182- delete (data) async {
196+ delete (data) async {
183197 var url = Uri .parse ("${AppConfig .backendUrl }/api/data" );
184198
185199 try {
@@ -198,6 +212,7 @@ delete (data) async {
198212 }
199213 } catch (e) {
200214 log.severe ('Exception occurred: $e ' );
215+ rethrow ;
201216 }
202217}
203218
@@ -219,7 +234,11 @@ Future<String> getDatabasePath() async {
219234
220235Future <void > openDatabase () async {
221236 // Open the local database
222- db = PowerSyncDatabase (schema: schema, path: await getDatabasePath ());
237+ db = PowerSyncDatabase (
238+ schema: schema,
239+ path: await getDatabasePath (),
240+ logger: attachedLogger,
241+ );
223242 await db.initialize ();
224243 BackendConnector ? currentConnector;
225244
@@ -235,9 +254,7 @@ Future<void> openDatabase() async {
235254 log.info ('User not logged in, setting connection' );
236255 }
237256
238- FirebaseAuth .instance
239- .authStateChanges ()
240- .listen ((User ? user) async {
257+ FirebaseAuth .instance.authStateChanges ().listen ((User ? user) async {
241258 if (user != null ) {
242259 // Connect to PowerSync when the user is signed in
243260 currentConnector = BackendConnector (db);
@@ -252,5 +269,5 @@ Future<void> openDatabase() async {
252269/// Explicit sign out - clear database and log out.
253270Future <void > logout () async {
254271 await FirebaseAuth .instance.signOut ();
255- await db.disconnectedAndClear ();
272+ await db.disconnectAndClear ();
256273}
0 commit comments