diff --git a/example/lib/main.dart b/example/lib/main.dart index e70d2dfaa..e388c77a8 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -5,6 +5,7 @@ import 'package:flutter_plugin_example/application_constants.dart'; import 'package:flutter_plugin_example/diet_plan.dart'; import 'package:parse_server_sdk/objects/parse_object.dart'; import 'package:parse_server_sdk/network/parse_query.dart'; +import 'package:parse_server_sdk/objects/parse_response.dart'; import 'package:parse_server_sdk/objects/parse_user.dart'; import 'package:parse_server_sdk/parse.dart'; @@ -52,11 +53,22 @@ class _MyAppState extends State { runTestQueries(){ getAllItems(); + getAllItemsByName(); getSingleItem(); query(); initUser(); } + void getAllItemsByName() async { + var apiResponse = await ParseObject('ParseTableName').getAll(); + + if (apiResponse.success){ + for (var testObject in apiResponse.result) { + print(ApplicationConstants.APP_NAME + ": " + testObject.toString()); + } + } + } + void getAllItems() async { var dietPlans = await DietPlan().getAll(); @@ -89,7 +101,7 @@ class _MyAppState extends State { if (response.success) { print(ApplicationConstants.APP_NAME + ": " + - ((response.result as List)[0] as DietPlan) + ((response.result as List).first as DietPlan) .toString()); } else { print(ApplicationConstants.APP_NAME + @@ -100,10 +112,7 @@ class _MyAppState extends State { } initUser() async { - User().createNewUser("TestFlutter", "TestPassword123", "TestEmail@Email.com"); - - User().login().then((val) { - print(val); - }); + ParseUser().create("TestFlutter", "TestPassword123", "TestFlutterSDK@gmail.com"); + ParseUser().signUp(); } } diff --git a/lib/base/parse_constants.dart b/lib/base/parse_constants.dart index 80a4b5b44..40052d27b 100644 --- a/lib/base/parse_constants.dart +++ b/lib/base/parse_constants.dart @@ -4,4 +4,7 @@ class ParseConstants { static const String OBJECT_ID = 'objectId'; static const String CREATED_AT = 'createdAt'; static const String UPDATED_AT = 'updatedAT'; + + static const String HEADER_SESSION_TOKEN = 'X-Parse-Session-Token'; + static const String HEADER_REVOCABLE_SESSION = 'X-Parse-Revocable-Session'; } \ No newline at end of file diff --git a/lib/data/parse_data_user.dart b/lib/data/parse_data_user.dart index 8abac9745..6fcf17b5b 100644 --- a/lib/data/parse_data_user.dart +++ b/lib/data/parse_data_user.dart @@ -1,21 +1,45 @@ -class ParseDataUser { - static ParseDataUser _instance; +import 'package:parse_server_sdk/objects/parse_base.dart'; - static ParseDataUser get instance => _instance; +class User extends ParseBase { + static User _instance; + + static User get instance => _instance; static void init(username, password, emailAddress) => - _instance ??= ParseDataUser._init(username, password, emailAddress); + _instance ??= User._init(username, password, emailAddress); + String acl; String username; String password; String emailAddress; - ParseDataUser._init(this.username, this.password, this.emailAddress); + User._init(this.username, this.password, this.emailAddress): super(); + + factory User() => _instance; + + fromJson(Map objectData) { + setObjectData(objectData); - factory ParseDataUser() => _instance; + acl = getObjectData()[ACL]; + username = getObjectData()[USERNAME]; + password = getObjectData()[PASSWORD]; + emailAddress = getObjectData()[EMAIL]; + return this; + } + + Map toJson() => { + ACL: acl, + USERNAME: username, + PASSWORD: password, + EMAIL: emailAddress, + }; @override - String toString() => - "Username: $username \n" + String toString() => "Username: $username \n" "Email Address:$emailAddress"; + + static const String USERNAME = 'Username'; + static const String EMAIL = 'Email'; + static const String PASSWORD = 'Password'; + static const String ACL = 'ACL'; } diff --git a/lib/data/parse_user_data.dart b/lib/data/parse_user_data.dart deleted file mode 100644 index 1fc1861e6..000000000 --- a/lib/data/parse_user_data.dart +++ /dev/null @@ -1,21 +0,0 @@ -class ParseUserData { - static ParseUserData _instance; - - static ParseUserData get instance => _instance; - - static void init(username, password, emailAddress) => - _instance ??= ParseUserData._init(username, password, emailAddress); - - String username; - String password; - String emailAddress; - - ParseUserData._init(this.username, this.password, this.emailAddress); - - factory ParseUserData() => _instance; - - @override - String toString() => - "Username: $username \n" - "Email Address:$emailAddress"; -} diff --git a/lib/enums/parse_enum_object_call.dart b/lib/enums/parse_enum_object_call.dart new file mode 100644 index 000000000..c57044a59 --- /dev/null +++ b/lib/enums/parse_enum_object_call.dart @@ -0,0 +1,26 @@ +enum ParseApiObjectCallType { + get, getAll, create, save, query, delete +} + +getEnumValue(ParseApiObjectCallType type){ + switch (type){ + case ParseApiObjectCallType.get: { + return 'get'; + } + case ParseApiObjectCallType.getAll: { + return 'getAll'; + } + case ParseApiObjectCallType.create: { + return 'create'; + } + case ParseApiObjectCallType.save: { + return 'save'; + } + case ParseApiObjectCallType.query: { + return 'query'; + } + case ParseApiObjectCallType.delete: { + return 'delete'; + } + } +} \ No newline at end of file diff --git a/lib/enums/parse_enum_user_call.dart b/lib/enums/parse_enum_user_call.dart new file mode 100644 index 000000000..9d9c5dbf4 --- /dev/null +++ b/lib/enums/parse_enum_user_call.dart @@ -0,0 +1,32 @@ +enum ParseApiUserCallType { + currentUser, signUp, login, verificationEmailRequest, requestPasswordReset, save, destroy, all +} + +getEnumValue(ParseApiUserCallType type){ + switch (type){ + case ParseApiUserCallType.currentUser: { + return 'currentUser'; + } + case ParseApiUserCallType.signUp: { + return 'signUp'; + } + case ParseApiUserCallType.login: { + return 'login'; + } + case ParseApiUserCallType.verificationEmailRequest: { + return 'verificationEmailRequest'; + } + case ParseApiUserCallType.requestPasswordReset: { + return 'requestPasswordReset'; + } + case ParseApiUserCallType.save: { + return 'save'; + } + case ParseApiUserCallType.destroy: { + return 'destroy'; + } + case ParseApiUserCallType.all: { + return 'all'; + } + } +} \ No newline at end of file diff --git a/lib/network/parse_query.dart b/lib/network/parse_query.dart index ff96ce15f..af0e94741 100644 --- a/lib/network/parse_query.dart +++ b/lib/network/parse_query.dart @@ -1,12 +1,11 @@ import 'dart:async'; import 'dart:convert'; -import 'package:parse_server_sdk/objects/parse_base.dart'; import 'package:parse_server_sdk/network/parse_http_client.dart'; import 'package:parse_server_sdk/objects/parse_object.dart'; import 'package:parse_server_sdk/objects/parse_response.dart'; -class QueryBuilder extends ParseBaseObject { +class QueryBuilder { ParseObject object; final ParseHTTPClient client = ParseHTTPClient(); @@ -53,7 +52,7 @@ class QueryBuilder extends ParseBaseObject { return new Future(foo); } - Future query() async { + query() async { return object.query(_buildQuery()); } diff --git a/lib/objects/parse_base.dart b/lib/objects/parse_base.dart index 3b17adb11..a5b03d651 100644 --- a/lib/objects/parse_base.dart +++ b/lib/objects/parse_base.dart @@ -1,106 +1,46 @@ import 'dart:convert'; import 'package:meta/meta.dart'; -import 'package:parse_server_sdk/network/parse_http_client.dart'; - -abstract class ParseBaseObject { - ParseHTTPClient _client; +abstract class ParseBase { Map _objectData; + String get objectId => _objectData['objectId']; + DateTime get createdAt => _objectData['createdAt']; - DateTime get updatedAt => _objectData['updatedAt']; - ParseBaseObject([this._client]){ - _objectData = Map(); - } + DateTime get updatedAt => _objectData['updatedAt']; @protected - setClient(ParseHTTPClient client) => _client = client; + toJson() => JsonEncoder().convert(getObjectData()); + @protected - getDebugStatus() => _client.data.debug; + copy() => JsonDecoder().convert(fromJson(getObjectData())); + @protected - getAppName() => _client.data.appName; + setObjectData(Map objectData) => _objectData = objectData; + @protected getObjectData() => _objectData; + @protected fromJson(Map objectData) => objectData; - toJson() => JsonEncoder().convert(getObjectData()); - - copy() { - var copy = fromJson(_objectData); - return JsonDecoder().convert(copy); - } - - _getBasePath(String path) => "${_client.data.serverUrl}$path"; - setValue(String key, dynamic value, {bool forceUpdate: true}) { if (value != null) { - if (_objectData.containsKey(key)) { - if (forceUpdate) _objectData[key] = value; + if (getObjectData().containsKey(key)) { + if (forceUpdate) getObjectData()[key] = value; } else { - _objectData[key] = value; + getObjectData()[key] = value; } } } getValue(String key, {dynamic defaultValue, bool fromServer}) { - if (_objectData.containsKey(key)) { - return _objectData[key]; + if (getObjectData().containsKey(key)) { + return getObjectData()[key]; } else { return defaultValue; } } - - _get(String objectId, String path) async { - var uri = _getBasePath(path); - if (objectId != null) uri += "/$objectId"; - return _client.get(uri); - } - - _getAll(String path) async { - return _client.get(_getBasePath(path)); - } - - @protected - parseGetAll(String path) => _getAll(path); - @protected - parseGetObjectById(String objectId, String path) => _get(objectId, path); - - _create(String path) async { - var uri = _client.data.serverUrl + "$path"; - return _client.post(uri, body: JsonEncoder().convert(_objectData)); - } - - @protected - parseCreate(String path, Map objectData) => _create(path); - - _save(String path) { - if (_objectData == null) { - return _create(path); - } else { - var uri = "${_getBasePath(path)}/$objectId"; - return _client.put(uri, body: JsonEncoder().convert(_objectData)); - } - } - - @protected - parseSave(String path) => _save(path); - - _query(String path, String query) async { - var uri = "${_getBasePath(path)}?$query"; - return _client.get(uri); - } - - @protected - parseQuery(String path, String query) => _query(path, query); - - _delete(String path, String objectId){ - var uri = "${_getBasePath(path)}/$objectId"; - return _client.delete(uri); - } - - @protected - parseDelete(String path, String query) => _delete(path, objectId); } diff --git a/lib/objects/parse_object.dart b/lib/objects/parse_object.dart index 8c729198f..0975d688d 100644 --- a/lib/objects/parse_object.dart +++ b/lib/objects/parse_object.dart @@ -1,66 +1,92 @@ +import 'dart:convert'; + import 'package:http/http.dart'; import 'package:meta/meta.dart'; +import 'package:parse_server_sdk/enums/parse_enum_object_call.dart'; import 'package:parse_server_sdk/network/parse_http_client.dart'; import 'package:parse_server_sdk/objects/parse_base.dart'; import 'package:parse_server_sdk/objects/parse_response.dart'; -class ParseObject extends ParseBaseObject { +class ParseObject extends ParseBase { final String className; - String path; - bool debug; + String _path; + bool _debug; + ParseHTTPClient _client; - ParseObject(this.className, {this.debug: false}) : super(ParseHTTPClient()) { - path = "/classes/$className"; + ParseObject(this.className, {bool debug: false, ParseHTTPClient client}) { + _debug = debug; + _path = "/classes/$className"; + setObjectData(Map()); + client == null ? _client = ParseHTTPClient() : _client = client; } - get(String id) async { - var result = await parseGetObjectById(id, path); - return _handleResult(result); + get(String objectId) async { + var uri = _getBasePath(_path); + if (objectId != null) uri += "/$objectId"; + var result = await _client.get(uri); + return _handleResult(result, ParseApiObjectCallType.get); } getAll() async { - var result = await parseGetAll(path); - return _handleResult(result); + var result = await _client.get(_getBasePath(_path)); + return _handleResult(result, ParseApiObjectCallType.getAll); } create([Map objectData]) async { - var result = await parseCreate(path, objectData); - return _handleResult(result); + var uri = _client.data.serverUrl + "$_path"; + var result = + await _client.post(uri, body: JsonEncoder().convert(getObjectData())); + return _handleResult(result, ParseApiObjectCallType.create); } save() async { - var result = await parseSave(path); - return _handleResult(result); + if (getObjectData() == null) { + return create(); + } else { + var uri = "${_getBasePath(_path)}/$objectId"; + var result = + await _client.put(uri, body: JsonEncoder().convert(getObjectData())); + return _handleResult(result, ParseApiObjectCallType.save); + } } @protected query(String query) async { - var result = await parseQuery(path, query); - return _handleResult(result); + var uri = "${_getBasePath(_path)}?$query"; + var result = await _client.get(uri); + return _handleResult(result, ParseApiObjectCallType.query); } - _handleResult(Response response) { - ParseResponse parseResponse = ParseResponse.handleResponse(this, response); + delete(String path, String objectId) async { + var uri = "${_getBasePath(path)}/$objectId"; + var result = await _client.delete(uri); + return _handleResult(result, ParseApiObjectCallType.delete); + } + + _getBasePath(String path) => "${_client.data.serverUrl}$path"; - if (getDebugStatus() || debug) { + ParseResponse _handleResult(Response response, ParseApiObjectCallType type) { + ParseResponse parseResponse = ParseResponse.handleResponse(this, response); + Map responseData = JsonDecoder().convert(response.body); - var responseString = " \n"; + if (_client.data.debug || _debug) { + var responseString = ' \n'; - responseString += - "----" - "\n${getAppName()} API Response:" + - "\nStatus Code: ${parseResponse.statusCode}"; + responseString += "----" + "\n${_client.data.appName} API Response ($className : ${getEnumValue(type)}) :"; if (parseResponse.success && parseResponse.result != null) { - responseString += "\nPayload: ${parseResponse.result.toString()}"; + responseString += "\nStatus Code: ${parseResponse.statusCode}"; + responseString += "\nPayload: ${responseData.toString()}"; } else if (!parseResponse.success) { - responseString += "\nException: ${parseResponse.exception.message}"; + responseString += "\nStatus Code: ${responseData['code']}"; + responseString += "\nException: ${responseData['error']}"; } - responseString += "\n----"; + responseString += "\n----\n"; print(responseString); } - return ParseResponse.handleResponse(this, response); + return parseResponse; } } diff --git a/lib/objects/parse_response.dart b/lib/objects/parse_response.dart index 6739c2bd9..0a7c9224a 100644 --- a/lib/objects/parse_response.dart +++ b/lib/objects/parse_response.dart @@ -40,18 +40,17 @@ class ParseResponse { return response; } - static List _handleMultipleResults( - ParseObject object, dynamic map) { - var resultsList = List(); + static _handleMultipleResults(ParseObject object, dynamic map) { + var resultsList = List(); for (var value in map) { - resultsList.add(_handleSingleResult(object.copy(), value)); + resultsList.add(_handleSingleResult(object, value)); } return resultsList; } - static ParseObject _handleSingleResult(ParseObject object, map) { + static _handleSingleResult(ParseObject object, map) { ParseUtilsObjects.populateObjectBaseData(object, map); return object.fromJson(map); } diff --git a/lib/objects/parse_user.dart b/lib/objects/parse_user.dart index 54c0c4936..35df6b3f8 100644 --- a/lib/objects/parse_user.dart +++ b/lib/objects/parse_user.dart @@ -1,157 +1,152 @@ import 'dart:convert'; -import 'dart:async'; +import 'package:http/http.dart'; +import 'package:parse_server_sdk/base/parse_constants.dart'; import 'package:parse_server_sdk/data/parse_data_user.dart'; - -import 'package:parse_server_sdk/objects/parse_base.dart'; +import 'package:parse_server_sdk/enums/parse_enum_user_call.dart'; import 'package:parse_server_sdk/network/parse_http_client.dart'; -class User extends ParseBaseObject { +class ParseUser { + ParseHTTPClient _client; static final String className = '_User'; - final ParseHTTPClient client = ParseHTTPClient(); - String path = "/classes/_User"; - Map objectData = {}; - - static ParseDataUser userData; - - User() : super(ParseHTTPClient()); + String path = "/classes/$className"; + bool debug; - String get objectId => objectData['objectId']; - String get sessionId => objectData['sessionToken']; - String get userId => objectData['objectId']; - - User createNewUser(String username, String password, String emailAddress) { - ParseDataUser.init(username, password, emailAddress); - userData = ParseDataUser(); - return _newInstance(ParseDataUser()); + ParseUser({this.debug: false, ParseHTTPClient client}) { + client != null ? _client = client : _client = ParseHTTPClient(); } - User _newInstance(ParseDataUser data) { + create(String username, String password, String emailAddress) { + User.init(username, password, emailAddress.toLowerCase()); return User(); } - Future me(attribute) async { - final response = this.client.get(client.data.serverUrl + "$path/me", - headers: {"X-Parse-Session-Token": sessionId}); - return response.then((value) { - objectData = JsonDecoder().convert(value.body); - return objectData[attribute]; - }); - } + _getBasePath(String path) => "${_client.data.serverUrl}$path"; - Map _handleResponse(String response) { - Map responseData = JsonDecoder().convert(response); - if (responseData.containsKey('objectId')) { - objectData = responseData; - this.client.data.sessionId = sessionId; + currentUser({bool fromServer: false}) async { + if (User() == null) { + return null; + } else if (fromServer == false) { + return User(); + } else { + var uri = "${_getBasePath(path)}/me"; + var result = await _client.get(uri, headers: { + ParseConstants.HEADER_SESSION_TOKEN: _client.data.sessionId + }); + return _handleResult(result, ParseApiUserCallType.currentUser); } - return responseData; - } - - void _resetObjectId() { - if (objectId != null) objectData.remove('objectId'); - if (sessionId != null) objectData.remove('sessionToken'); } - Future> signUp([Map objectInitialData]) async { - if (objectInitialData != null) { - objectData = {}..addAll(objectData)..addAll(objectInitialData); - } - _resetObjectId(); - + signUp() async { Map bodyData = {}; - bodyData["email"] = userData.username; - bodyData["password"] = userData.password; - bodyData["username"] = userData.username; + bodyData["email"] = User().emailAddress; + bodyData["password"] = User().password; + bodyData["username"] = User().username; - Uri tempUri = Uri.parse(client.data.serverUrl); + Uri tempUri = Uri.parse(_client.data.serverUrl); Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, - path: "${tempUri.path}$path" - ); + path: "${tempUri.path}$path"); - final response = this.client.post(url, + final response = await _client.post(url, headers: { - 'X-Parse-Revocable-Session': "1", + ParseConstants.HEADER_REVOCABLE_SESSION: "1", }, body: JsonEncoder().convert(bodyData)); - return response.then((value) { - _handleResponse(value.body); - return objectData; - }); + _handleResult(response, ParseApiUserCallType.signUp); + return User(); } - Future> login() async { - Uri tempUri = Uri.parse(client.data.serverUrl); + login() async { + Uri tempUri = Uri.parse(_client.data.serverUrl); Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, path: "${tempUri.path}/login", queryParameters: { - "username": userData.username, - "password": userData.password - } - ); + "username": User().username, + "password": User().password + }); - final response = this.client.post(url, headers: { - 'X-Parse-Revocable-Session': "1", - }); - return response.then((value) { - _handleResponse(value.body); - return objectData; + final response = await _client.post(url, headers: { + ParseConstants.HEADER_REVOCABLE_SESSION: "1", }); + + _handleResult(response, ParseApiUserCallType.login); + return User(); } - Future> verificationEmailRequest() async { - final response = this.client.post( - "${client.data.serverUrl}/verificationEmailRequest", - body: JsonEncoder().convert({"email": userData.emailAddress})); - return response.then((value) { - return _handleResponse(value.body); - }); + verificationEmailRequest() async { + final response = await _client.post( + "${_client.data.serverUrl}/verificationEmailRequest", + body: JsonEncoder().convert({"email": User().emailAddress})); + + return _handleResult( + response, ParseApiUserCallType.verificationEmailRequest); } - Future> requestPasswordReset() async { - final response = this.client.post( - "${client.data.serverUrl}/requestPasswordReset", - body: JsonEncoder().convert({"email": userData.emailAddress})); - return response.then((value) { - return _handleResponse(value.body); - }); + requestPasswordReset() async { + final response = await _client.post( + "${_client.data.serverUrl}/requestPasswordReset", + body: JsonEncoder().convert({"email": User().emailAddress})); + + return _handleResult(response, ParseApiUserCallType.requestPasswordReset); } - Future> save([Map objectInitialData]) { - objectData = {}..addAll(objectData)..addAll(objectInitialData); - if (objectId == null) { - return signUp(objectData); + save() async { + if (User().objectId == null) { + return signUp(); } else { - final response = this.client.put( - client.data.serverUrl + "$path/$objectId", - body: JsonEncoder().convert(objectData)); - return response.then((value) { - return _handleResponse(value.body); - }); + final response = await _client.put( + _client.data.serverUrl + "$path/${User().objectId}", + body: JsonEncoder().convert(User().getObjectData())); + return _handleResult(response, ParseApiUserCallType.save); } } - Future destroy() { - final response = this.client.delete( - client.data.serverUrl + "$path/$objectId", - headers: {"X-Parse-Session-Token": sessionId}); - return response.then((value) { - _handleResponse(value.body); - return objectId; - }); + destroy() async { + final response = await _client.delete( + _client.data.serverUrl + "$path/${User().objectId}", + headers: {"X-Parse-Session-Token": _client.data.sessionId}); + _handleResult(response, ParseApiUserCallType.destroy); + return User().objectId; } - Future> all() { - final response = this.client.get(client.data.serverUrl + "$path"); - return response.then((value) { - return _handleResponse(value.body); - }); + all() async { + final response = await _client.get(_client.data.serverUrl + "$path"); + return _handleResult(response, ParseApiUserCallType.all); + } + + _handleResult(Response response, ParseApiUserCallType type) { + Map responseData = JsonDecoder().convert(response.body); + + var responseString = ' \n'; + + responseString += "----" + "\n${_client.data.appName} API Response ($className : ${getEnumValue(type)}) :"; + + if (response.statusCode == 200) { + responseString += "\nStatus Code: ${response.statusCode}"; + responseString += "\nPayload: ${responseData.toString()}"; + + if (responseData.containsKey('objectId')) { + User().fromJson(JsonDecoder().convert(response.body) as Map); + _client.data.sessionId = responseData['sessionId']; + } + } else { + responseString += "\nStatus Code: ${responseData['code']}"; + responseString += "\nException: ${responseData['error']}"; + } + + if (_client.data.debug || debug) { + responseString += "\n----\n"; + print(responseString); + } + + return User(); } } diff --git a/lib/parse.dart b/lib/parse.dart index 5372a026a..49081e8bf 100644 --- a/lib/parse.dart +++ b/lib/parse.dart @@ -33,7 +33,7 @@ class Parse { ParseObject _parseObject; // ignore: unused_field - User _user; + ParseUser _user; // ignore: unused_field LiveQuery _liveQuery; @@ -42,8 +42,8 @@ class Parse { return _parseObject = new ParseObject(objectName); } - User user() { - return _user = new User(); + ParseUser user() { + return _user = new ParseUser(); } LiveQuery liveQuery() {