From d08793aea8c701544161218420c72adbb3a597b0 Mon Sep 17 00:00:00 2001 From: matskosan Date: Sat, 10 Aug 2019 19:53:55 +0200 Subject: [PATCH 1/5] Added some missing async/await (#248) * Updated dependencies. * ParseUser._handleResponse was calling saveInStorage() async without an await, which caused 'invalid session token' error if user ParseUser.currentUser() immediately after ParseUser.signUp() or ParseUser.login(). Added missing awaits in other places. * ParseUser was not updated in storage after a successful save() operation. Reason: no safeInStorage() after save() was called. Fix: calling saveInStorage() after save(). * Revert "Updated dependencies." This reverts commit dbbc5e830bbded10936bab3ae7f76030316a7553. --- lib/src/objects/parse_base.dart | 7 +++-- lib/src/objects/parse_installation.dart | 8 ++--- lib/src/objects/parse_user.dart | 39 +++++++++++++++---------- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/lib/src/objects/parse_base.dart b/lib/src/objects/parse_base.dart index 01e1535bb..5d05dd767 100644 --- a/lib/src/objects/parse_base.dart +++ b/lib/src/objects/parse_base.dart @@ -46,6 +46,7 @@ abstract class ParseBase { if (value is ParseObject && value._areChildrenDirty(seenObjects)) { match = true; } + return false; }); return match; } @@ -177,7 +178,7 @@ abstract class ParseBase { /// Saves in storage Future saveInStorage(String key) async { final String objectJson = json.encode(toJson(full: true)); - ParseCoreData().getStore()..setString(key, objectJson); + await ParseCoreData().getStore().setString(key, objectJson); } /// Sets type [T] from objectData @@ -240,7 +241,7 @@ abstract class ParseBase { await unpin(); final Map objectMap = parseEncode(this, full: true); final String json = jsonEncode(objectMap); - ParseCoreData().getStore()..setString(objectId, json); + await ParseCoreData().getStore().setString(objectId, json); return true; } else { return false; @@ -252,7 +253,7 @@ abstract class ParseBase { /// Replicates Android SDK pin process and saves object to storage Future unpin({String key}) async { if (objectId != null) { - ParseCoreData().getStore()..remove(key ?? objectId); + await ParseCoreData().getStore().remove(key ?? objectId); return true; } diff --git a/lib/src/objects/parse_installation.dart b/lib/src/objects/parse_installation.dart index f94b5db61..60c22bf49 100644 --- a/lib/src/objects/parse_installation.dart +++ b/lib/src/objects/parse_installation.dart @@ -204,17 +204,17 @@ class ParseInstallation extends ParseObject { } ///Subscribes the device to a channel of push notifications. - void subscribeToChannel(String value) { + Future subscribeToChannel(String value) async { final List channel = [value]; setAddAllUnique('channels', channel); - save(); + await save(); } ///Unsubscribes the device to a channel of push notifications. - void unsubscribeFromChannel(String value) { + Future unsubscribeFromChannel(String value) async { final List channel = [value]; setRemove('channels', channel); - save(); + await save(); } ///Returns an > containing all the channel names this device is subscribed to. diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index b541eedeb..d9c73c2e1 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -105,7 +105,7 @@ class ParseUser extends ParseObject implements ParseCloneable { try { final Uri url = getSanitisedUri(_client, '$keyEndPointUserName'); final Response response = await _client.get(url, headers: headers); - return _handleResponse(_getEmptyUser(), response, ParseApiRQ.currentUser, + return await _handleResponse(_getEmptyUser(), response, ParseApiRQ.currentUser, _debug, _getEmptyUser().parseClassName); } on Exception catch (e) { return handleException( @@ -146,7 +146,7 @@ class ParseUser extends ParseObject implements ParseCloneable { }, body: body); - return _handleResponse( + return await _handleResponse( this, response, ParseApiRQ.signUp, _debug, parseClassName); } on Exception catch (e) { return handleException(e, ParseApiRQ.signUp, _debug, parseClassName); @@ -172,7 +172,7 @@ class ParseUser extends ParseObject implements ParseCloneable { keyHeaderRevocableSession: '1', }); - return _handleResponse( + return await _handleResponse( this, response, ParseApiRQ.login, _debug, parseClassName); } on Exception catch (e) { return handleException(e, ParseApiRQ.login, _debug, parseClassName); @@ -195,7 +195,7 @@ class ParseUser extends ParseObject implements ParseCloneable { } })); - return _handleResponse( + return await _handleResponse( this, response, ParseApiRQ.loginAnonymous, _debug, parseClassName); } on Exception catch (e) { return handleException( @@ -222,7 +222,7 @@ class ParseUser extends ParseObject implements ParseCloneable { 'authData': {provider: authData} })); - return _handleResponse( + return await _handleResponse( this, response, ParseApiRQ.loginWith, _debug, parseClassName); } on Exception catch (e) { return handleException(e, ParseApiRQ.loginWith, _debug, parseClassName); @@ -248,7 +248,7 @@ class ParseUser extends ParseObject implements ParseCloneable { final Response response = await _client.post(url, headers: {keyHeaderSessionToken: sessionId}); - return _handleResponse( + return await _handleResponse( this, response, ParseApiRQ.logout, _debug, parseClassName); } on Exception catch (e) { return handleException(e, ParseApiRQ.logout, _debug, parseClassName); @@ -261,7 +261,7 @@ class ParseUser extends ParseObject implements ParseCloneable { final Response response = await _client.post( '${_client.data.serverUrl}$keyEndPointVerificationEmail', body: json.encode({keyVarEmail: emailAddress})); - return _handleResponse(this, response, + return await _handleResponse(this, response, ParseApiRQ.verificationEmailRequest, _debug, parseClassName); } on Exception catch (e) { return handleException( @@ -275,8 +275,9 @@ class ParseUser extends ParseObject implements ParseCloneable { final Response response = await _client.post( '${_client.data.serverUrl}$keyEndPointRequestPasswordReset', body: json.encode({keyVarEmail: emailAddress})); - return _handleResponse(this, response, ParseApiRQ.requestPasswordReset, - _debug, parseClassName); + return await _handleResponse( + this, response, ParseApiRQ.requestPasswordReset, _debug, + parseClassName); } on Exception catch (e) { return handleException( e, ParseApiRQ.requestPasswordReset, _debug, parseClassName); @@ -290,19 +291,27 @@ class ParseUser extends ParseObject implements ParseCloneable { @override Future save() async { if (objectId == null) { - return signUp(); + return await signUp(); } else { - return super.save(); + final ParseResponse response = await super.save(); + if (response.success) { + await _onResponseSuccess(); + } + return response; } } + Future _onResponseSuccess() async { + await saveInStorage(keyParseStoreUser); + } + /// Removes a user from Parse Server locally and online Future destroy() async { if (objectId != null) { try { final Uri url = getSanitisedUri(_client, '$_path/$objectId'); final Response response = await _client.delete(url); - return _handleResponse( + return await _handleResponse( this, response, ParseApiRQ.destroy, _debug, parseClassName); } on Exception catch (e) { return handleException(e, ParseApiRQ.destroy, _debug, parseClassName); @@ -352,8 +361,8 @@ class ParseUser extends ParseObject implements ParseCloneable { } /// Handles all the response data for this class - static ParseResponse _handleResponse(ParseUser user, Response response, - ParseApiRQ type, bool debug, String className) { + static Future _handleResponse(ParseUser user, Response response, + ParseApiRQ type, bool debug, String className) async { final ParseResponse parseResponse = handleResponse(user, response, type, debug, className); @@ -372,7 +381,7 @@ class ParseUser extends ParseObject implements ParseCloneable { return parseResponse; } else { final ParseUser user = parseResponse.result; - user?.saveInStorage(keyParseStoreUser); + await user?._onResponseSuccess(); return parseResponse; } } From c2684c3d614df33a37783a8da4bf614cfaf2e4f9 Mon Sep 17 00:00:00 2001 From: Oleksandr Matsko Date: Wed, 14 Aug 2019 07:25:46 +0200 Subject: [PATCH 2/5] forceUpdate was ignored when setting ParseBase properties --- lib/src/objects/parse_base.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/objects/parse_base.dart b/lib/src/objects/parse_base.dart index 5d05dd767..415a4c1ed 100644 --- a/lib/src/objects/parse_base.dart +++ b/lib/src/objects/parse_base.dart @@ -189,7 +189,7 @@ abstract class ParseBase { void set(String key, T value, {bool forceUpdate = true}) { if (value != null) { if (_getObjectData().containsKey(key)) { - if (_getObjectData()[key] == value) { + if (_getObjectData()[key] == value && !forceUpdate) { return; } _getObjectData()[key] = From 5c170dbe10e35dc5cf71998bb53485c260038b5d Mon Sep 17 00:00:00 2001 From: Oleksandr Matsko Date: Wed, 14 Aug 2019 07:47:13 +0200 Subject: [PATCH 3/5] Setting objectData properties directly in parseJson function to prevent making decoded object properties dirty --- lib/src/objects/parse_base.dart | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/src/objects/parse_base.dart b/lib/src/objects/parse_base.dart index 415a4c1ed..9929eaf53 100644 --- a/lib/src/objects/parse_base.dart +++ b/lib/src/objects/parse_base.dart @@ -122,23 +122,23 @@ abstract class ParseBase { if (key == parseClassName || key == '__type') { // NO OP } else if (key == keyVarObjectId) { - objectId = value; + _getObjectData()[keyVarObjectId] = value; } else if (key == keyVarCreatedAt) { if (keyVarCreatedAt is String) { - set(keyVarCreatedAt, _parseDateFormat.parse(value)); + _getObjectData()[keyVarCreatedAt] = _parseDateFormat.parse(value); } else { - set(keyVarCreatedAt, value); + _getObjectData()[keyVarCreatedAt] = value; } } else if (key == keyVarUpdatedAt) { if (keyVarUpdatedAt is String) { - set(keyVarUpdatedAt, _parseDateFormat.parse(value)); + _getObjectData()[keyVarUpdatedAt] = _parseDateFormat.parse(value); } else { - set(keyVarUpdatedAt, value); + _getObjectData()[keyVarUpdatedAt] = _parseDateFormat.parse(value); } } else if (key == keyVarAcl) { - this[keyVarAcl] = ParseACL().fromJson(value); + _getObjectData()[keyVarAcl] = ParseACL().fromJson(value); } else { - this[key] = parseDecode(value); + _getObjectData()[key] = parseDecode(value); } }); From 0a0ef5b5d433d83e33e9030ac76eff3444331b6f Mon Sep 17 00:00:00 2001 From: Oleksandr Matsko Date: Wed, 14 Aug 2019 07:48:05 +0200 Subject: [PATCH 4/5] Made forceUpdate false by default in ParseBase set method --- lib/src/objects/parse_base.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/objects/parse_base.dart b/lib/src/objects/parse_base.dart index 9929eaf53..f07d7beba 100644 --- a/lib/src/objects/parse_base.dart +++ b/lib/src/objects/parse_base.dart @@ -186,7 +186,7 @@ abstract class ParseBase { /// To set an int, call setType and an int will be saved /// [bool] forceUpdate is always true, if unsure as to whether an item is /// needed or not, set to false - void set(String key, T value, {bool forceUpdate = true}) { + void set(String key, T value, {bool forceUpdate = false}) { if (value != null) { if (_getObjectData().containsKey(key)) { if (_getObjectData()[key] == value && !forceUpdate) { From 378aa5fe386771bead0345f8ee56ca8bfa49a11b Mon Sep 17 00:00:00 2001 From: Oleksandr Matsko Date: Wed, 14 Aug 2019 09:32:33 +0200 Subject: [PATCH 5/5] Revert incorrect merge --- lib/src/objects/parse_base.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/objects/parse_base.dart b/lib/src/objects/parse_base.dart index f07d7beba..eb6f3d199 100644 --- a/lib/src/objects/parse_base.dart +++ b/lib/src/objects/parse_base.dart @@ -46,7 +46,6 @@ abstract class ParseBase { if (value is ParseObject && value._areChildrenDirty(seenObjects)) { match = true; } - return false; }); return match; }