From c609cce59f427a8502d40876084a3e0dd53f77e8 Mon Sep 17 00:00:00 2001 From: Murali Regandla Date: Sat, 14 Dec 2019 17:49:41 +0530 Subject: [PATCH 1/5] Setting installationId in _Session object during sign-up --- lib/src/base/parse_constants.dart | 1 + lib/src/objects/parse_user.dart | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/src/base/parse_constants.dart b/lib/src/base/parse_constants.dart index 8c13d3807..b003e9679 100644 --- a/lib/src/base/parse_constants.dart +++ b/lib/src/base/parse_constants.dart @@ -49,6 +49,7 @@ const String keyHeaderContentType = 'Content-Type'; const String keyHeaderContentTypeJson = 'application/json'; const String keyHeaderMasterKey = 'X-Parse-Master-Key'; const String keyHeaderClientKey = 'X-Parse-Client-Key'; +const String keyHeaderInstallationId = 'X-Parse-Installation-Id'; // URL params const String keyParamSessionToken = 'sessionToken'; diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index c9791e5a0..1db05a8f0 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -33,8 +33,7 @@ class ParseUser extends ParseObject implements ParseCloneable { @override dynamic clone(Map map) => - ParseUser.clone(map) - ..fromJson(map); + ParseUser.clone(map)..fromJson(map); static const String keyEmailVerified = 'emailVerified'; static const String keyUsername = 'username'; @@ -141,9 +140,11 @@ class ParseUser extends ParseObject implements ParseCloneable { final Uri url = getSanitisedUri(_client, '$path'); final String body = json.encode(bodyData); _saveChanges(); + final String installationId = await _getInstallationId(); final Response response = await _client.post(url, headers: { keyHeaderRevocableSession: '1', + if (installationId != null) keyHeaderInstallationId: installationId, }, body: body); @@ -185,10 +186,12 @@ class ParseUser extends ParseObject implements ParseCloneable { try { final Uri url = getSanitisedUri(_client, '$keyEndPointUsers'); final Uuid uuid = Uuid(); + final String installationId = await _getInstallationId(); final Response response = await _client.post(url, headers: { keyHeaderRevocableSession: '1', + if (installationId != null) keyHeaderInstallationId: installationId, }, body: jsonEncode({ 'authData': { @@ -215,9 +218,11 @@ class ParseUser extends ParseObject implements ParseCloneable { Future _loginWith(String provider, Object authData) async { try { final Uri url = getSanitisedUri(_client, '$keyEndPointUsers'); + final String installationId = await _getInstallationId(); final Response response = await _client.post(url, headers: { keyHeaderRevocableSession: '1', + if (installationId != null) keyHeaderInstallationId: installationId, }, body: jsonEncode({ 'authData': {provider: authData} @@ -396,4 +401,10 @@ class ParseUser extends ParseObject implements ParseCloneable { } static ParseUser _getEmptyUser() => ParseUser(null, null, null); + + static Future _getInstallationId() async { + final ParseInstallation parseInstallation = + await ParseInstallation.currentInstallation(); + return parseInstallation?.installationId; + } } From a797ab892c9630392b6da1792f799bcbbbef53b8 Mon Sep 17 00:00:00 2001 From: Murali Regandla Date: Tue, 17 Dec 2019 12:45:00 +0530 Subject: [PATCH 2/5] example app migration to use Sembast v2 --- example/android/app/build.gradle | 8 +-- example/android/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../diet_plan/provider_db_diet_plan.dart | 43 ++++++++++----- .../diet_plan/repository_diet_plan.dart | 3 +- .../repositories/user/provider_db_user.dart | 18 ++++--- .../repositories/user/repository_user.dart | 3 +- example/lib/main.dart | 54 ++++++++++--------- example/lib/pages/home_page.dart | 4 +- 9 files changed, 82 insertions(+), 55 deletions(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 9883bcabb..062011fe4 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -15,7 +15,7 @@ apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 27 + compileSdkVersion 28 lintOptions { disable 'InvalidPackage' @@ -25,7 +25,7 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.flutterpluginexample" minSdkVersion 16 - targetSdkVersion 27 + targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -46,6 +46,6 @@ flutter { dependencies { testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' } diff --git a/example/android/build.gradle b/example/android/build.gradle index 447688755..6de372893 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'com.android.tools.build:gradle:3.5.3' } } diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index aa901e1e0..9b6616cb7 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip diff --git a/example/lib/data/repositories/diet_plan/provider_db_diet_plan.dart b/example/lib/data/repositories/diet_plan/provider_db_diet_plan.dart index 4ad891866..6915520c0 100644 --- a/example/lib/data/repositories/diet_plan/provider_db_diet_plan.dart +++ b/example/lib/data/repositories/diet_plan/provider_db_diet_plan.dart @@ -10,16 +10,18 @@ import 'package:sembast/sembast.dart'; class DietPlanProviderDB implements DietPlanProviderContract { DietPlanProviderDB(this._db, this._store); - final Store _store; + final StoreRef> _store; final Database _db; @override Future add(DietPlan item) async { final Map values = convertItemToStorageMap(item); - final Record recordToAdd = Record(_store, values, item.objectId); - final Record recordFromDB = await _db.putRecord(recordToAdd); + await _store.record(item.objectId).put(_db, values); + final Map recordFromDB = + await _store.record(item.objectId).get(_db); + return ApiResponse( - true, 200, [convertRecordToItem(record: recordFromDB)], null); + true, 200, [convertRecordToItem(values: recordFromDB)], null); } @override @@ -48,10 +50,12 @@ class DietPlanProviderDB implements DietPlanProviderContract { final List sortOrders = List(); sortOrders.add(SortOrder(keyName)); final Finder finder = Finder(sortOrders: sortOrders); - final List records = await _store.findRecords(finder); + final List>> records = + await _store.find(_db, finder: finder); if (records.isNotEmpty) { - for (final Record record in records) { + for (final RecordSnapshot> record + in records) { final DietPlan userFood = convertRecordToItem(record: record); foodItems.add(userFood); } @@ -64,7 +68,10 @@ class DietPlanProviderDB implements DietPlanProviderContract { @override Future getById(String id) async { - final Record record = await _store.getRecord(id); + final Finder finder = Finder(filter: Filter.equals('objectId', id)); + + final RecordSnapshot> record = + await _store.findFirst(_db, finder: finder); if (record != null) { final DietPlan userFood = convertRecordToItem(record: record); return ApiResponse(true, 200, [userFood], null); @@ -81,9 +88,10 @@ class DietPlanProviderDB implements DietPlanProviderContract { filter: Filter.greaterThan(keyVarUpdatedAt, date.millisecondsSinceEpoch)); - final List records = await _store.findRecords(finder); + final List>> records = + await _store.find(_db, finder: finder); - for (final Record record in records) { + for (final RecordSnapshot> record in records) { final DietPlan convertedDietPlan = convertRecordToItem(record: record); foodItems.add(convertedDietPlan); } @@ -97,7 +105,9 @@ class DietPlanProviderDB implements DietPlanProviderContract { @override Future remove(DietPlan item) async { - await _store.delete(item.objectId); + final Finder finder = + Finder(filter: Filter.equals('objectId', item.objectId)); + _store.delete(_db, finder: finder); return ApiResponse(true, 200, null, null); } @@ -123,14 +133,17 @@ class DietPlanProviderDB implements DietPlanProviderContract { @override Future update(DietPlan item) async { final Map values = convertItemToStorageMap(item); - final dynamic returnedItems = await _store.update(values, item.objectId); + final Finder finder = + Finder(filter: Filter.equals('objectId', item.objectId)); + final int returnedCount = + await _store.update(_db, values, finder: finder); - if (returnedItems == null) { + if (returnedCount == 0) { return add(item); } return ApiResponse( - true, 200, [convertRecordToItem(values: returnedItems)], null); + true, 200, [item], null); } Map convertItemToStorageMap(DietPlan item) { @@ -145,7 +158,9 @@ class DietPlanProviderDB implements DietPlanProviderContract { return values; } - DietPlan convertRecordToItem({Record record, Map values}) { + DietPlan convertRecordToItem( + {RecordSnapshot> record, + Map values}) { try { values ??= record.value; final DietPlan item = diff --git a/example/lib/data/repositories/diet_plan/repository_diet_plan.dart b/example/lib/data/repositories/diet_plan/repository_diet_plan.dart index beaebff14..f0b523384 100644 --- a/example/lib/data/repositories/diet_plan/repository_diet_plan.dart +++ b/example/lib/data/repositories/diet_plan/repository_diet_plan.dart @@ -15,7 +15,8 @@ class DietPlanRepository implements DietPlanProviderContract { if (mockDBProvider != null) { repository.db = mockDBProvider; } else { - final Store store = dbConnection.getStore('repository_store'); + final StoreRef> store = + stringMapStoreFactory.store('repository_diet'); repository.db = DietPlanProviderDB(dbConnection, store); } diff --git a/example/lib/data/repositories/user/provider_db_user.dart b/example/lib/data/repositories/user/provider_db_user.dart index a7e5380e9..dff056796 100644 --- a/example/lib/data/repositories/user/provider_db_user.dart +++ b/example/lib/data/repositories/user/provider_db_user.dart @@ -11,7 +11,7 @@ import 'contract_provider_user.dart'; class UserProviderDB implements UserProviderContract { UserProviderDB(this._db, this._store); - final Store _store; + final StoreRef> _store; final Database _db; @override @@ -19,8 +19,9 @@ class UserProviderDB implements UserProviderContract { String username, String password, String emailAddress) async { final User user = User(username, password, emailAddress); final Map values = convertItemToStorageMap(user); - final Record recordToAdd = Record(_store, values, user.objectId); - final Record recordFromDB = await _db.putRecord(recordToAdd); + await _store.record(user.objectId).put(_db, values); + final Map recordFromDB = + await _store.record(user.objectId).get(_db); return convertRecordToItem(record: recordFromDB); } @@ -36,7 +37,9 @@ class UserProviderDB implements UserProviderContract { @override Future destroy(User user) async { - await _store.delete(user.objectId); + final Finder finder = + Finder(filter: Filter.equals('objectId', user.objectId)); + await _store.delete(_db, finder: finder); return ApiResponse(true, 200, null, null); } @@ -53,8 +56,9 @@ class UserProviderDB implements UserProviderContract { @override Future save(User user) async { final Map values = convertItemToStorageMap(user); - final Record recordToAdd = Record(_store, values, user.objectId); - final Record recordFromDB = await _db.putRecord(recordToAdd); + await _store.record(user.objectId).put(_db, values); + final Map recordFromDB = + await _store.record(user.objectId).get(_db); return ApiResponse( true, 200, [convertRecordToItem(record: recordFromDB)], null); } @@ -88,7 +92,7 @@ class UserProviderDB implements UserProviderContract { return values; } - User convertRecordToItem({Record record, Map values}) { + User convertRecordToItem({dynamic record, Map values}) { try { values ??= record.value; final User item = User.clone().fromJson(json.jsonDecode(values['value'])); diff --git a/example/lib/data/repositories/user/repository_user.dart b/example/lib/data/repositories/user/repository_user.dart index b9a5c26a0..ace932eaf 100644 --- a/example/lib/data/repositories/user/repository_user.dart +++ b/example/lib/data/repositories/user/repository_user.dart @@ -15,7 +15,8 @@ class UserRepository implements UserProviderContract { if (mockDBProvider != null) { repository.db = mockDBProvider; } else { - final Store store = dbConnection.getStore('reposutory_user'); + final StoreRef> store = + stringMapStoreFactory.store('repository_user'); repository.db = UserProviderDB(dbConnection, store); } diff --git a/example/lib/main.dart b/example/lib/main.dart index c8b7779ed..518525320 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -10,6 +10,7 @@ import 'package:flutter_plugin_example/data/repositories/diet_plan/repository_di import 'package:flutter_plugin_example/data/repositories/user/repository_user.dart'; import 'package:flutter_plugin_example/domain/constants/application_constants.dart'; import 'package:flutter_plugin_example/domain/utils/db_utils.dart'; +import 'package:flutter_plugin_example/pages/decision_page.dart'; import 'package:parse_server_sdk/parse_server_sdk.dart'; void main() { @@ -55,7 +56,9 @@ class _MyAppState extends State { title: const Text('Plugin example app'), ), body: Center( - child: Text(text), + //child: Text(text), + child: DecisionPage(), + //child: HomePage(), ), ), ); @@ -94,22 +97,22 @@ class _MyAppState extends State { Future runTestQueries() async { // Basic repository example - /* await repositoryAddUser(); - await repositoryAddItems(); + //await repositoryAddUser(); + // await repositoryAddItems(); await repositoryGetAllItems(); -*/ + //Basic usage - /* await createItem(); - await getAllItems(); - await getAllItemsByName(); - await getSingleItem(); - await getConfigs(); - await query();*/ - await initUser(); - /* await initInstallation(); - await function(); - await functionWithParameters(); - await test();*/ + //await createItem(); + //await getAllItems(); + //await getAllItemsByName(); + //await getSingleItem(); + //await getConfigs(); + //await query(); + //await initUser(); + //await initInstallation(); + //await function(); + //await functionWithParameters(); + //await test(); } Future initInstallation() async { @@ -221,7 +224,7 @@ class _MyAppState extends State { Future initUser() async { // All return type ParseUser except all ParseUser user = - ParseUser('RE9fU360lishjFKC5dLZS4Zwm', 'password', 'test@facebook.com'); + ParseUser('RE9fU360lishjFKC5dLZS4Zwm', 'password', 'test@facebook.com'); /// Sign-up /*ParseResponse response = await user.signUp(); @@ -353,7 +356,9 @@ class _MyAppState extends State { final List json = const JsonDecoder().convert(dietPlansToAdd); for (final Map element in json) { - final DietPlan dietPlan = DietPlan().fromJson(element); + final DietPlan dietPlan = DietPlan(); + element.forEach( + (String k, dynamic v) => dietPlan.set(k, parseDecode(v))); dietPlans.add(dietPlan); } @@ -376,7 +381,6 @@ class _MyAppState extends State { userRepo ??= UserRepository.init(await getDB()); } - /// Available options: /// SharedPreferences - Not secure but will work with older versions of SDK - CoreStoreSharedPrefsImpl /// Sembast - NoSQL DB - Has security - CoreStoreSembastImpl @@ -387,10 +391,10 @@ class _MyAppState extends State { } const String dietPlansToAdd = - '[{"className":"Diet_Plans","Name":"Textbook","Description":"For an active lifestyle and a straight forward macro plan, we suggest this plan.","Fat":25,"Carbs":50,"Protein":25,"Status":0},' - '{"className":"Diet_Plans","Name":"Body Builder","Description":"Default Body Builders Diet","Fat":20,"Carbs":40,"Protein":40,"Status":0},' - '{"className":"Diet_Plans","Name":"Zone Diet","Description":"Popular with CrossFit users. Zone Diet targets similar macros.","Fat":30,"Carbs":40,"Protein":30,"Status":0},' - '{"className":"Diet_Plans","Name":"Low Fat","Description":"Low fat diet.","Fat":15,"Carbs":60,"Protein":25,"Status":0},' - '{"className":"Diet_Plans","Name":"Low Carb","Description":"Low Carb diet, main focus on quality fats and protein.","Fat":35,"Carbs":25,"Protein":40,"Status":0},' - '{"className":"Diet_Plans","Name":"Paleo","Description":"Paleo diet.","Fat":60,"Carbs":25,"Protein":10,"Status":0},' - '{"className":"Diet_Plans","Name":"Ketogenic","Description":"High quality fats, low carbs.","Fat":65,"Carbs":5,"Protein":30,"Status":0}]'; + '[{"className":"Diet_Plans","Name":"Textbook","Description":"For an active lifestyle and a straight forward macro plan, we suggest this plan.","Fat":25,"Carbs":50,"Protein":25,"Status":false},' + '{"className":"Diet_Plans","Name":"Body Builder","Description":"Default Body Builders Diet","Fat":20,"Carbs":40,"Protein":40,"Status":false},' + '{"className":"Diet_Plans","Name":"Zone Diet","Description":"Popular with CrossFit users. Zone Diet targets similar macros.","Fat":30,"Carbs":40,"Protein":30,"Status":false},' + '{"className":"Diet_Plans","Name":"Low Fat","Description":"Low fat diet.","Fat":15,"Carbs":60,"Protein":25,"Status":false},' + '{"className":"Diet_Plans","Name":"Low Carb","Description":"Low Carb diet, main focus on quality fats and protein.","Fat":35,"Carbs":25,"Protein":40,"Status":false},' + '{"className":"Diet_Plans","Name":"Paleo","Description":"Paleo diet.","Fat":60,"Carbs":25,"Protein":10,"Status":false},' + '{"className":"Diet_Plans","Name":"Ketogenic","Description":"High quality fats, low carbs.","Fat":65,"Carbs":5,"Protein":30,"Status":false}]'; diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 00f569346..ea2259795 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -24,7 +24,9 @@ class _HomePageState extends State { super.initState(); final List json = const JsonDecoder().convert(dietPlansToAdd); for (final Map element in json) { - final DietPlan dietPlan = DietPlan().fromJson(element); + final DietPlan dietPlan = DietPlan(); + element.forEach( + (String k, dynamic v) => dietPlan.set(k, parseDecode(v))); randomDietPlans.add(dietPlan); } } From 91e4933561a69fcb78b59b885c07fe8e66da4de5 Mon Sep 17 00:00:00 2001 From: Murali Regandla Date: Tue, 17 Dec 2019 17:34:03 +0530 Subject: [PATCH 3/5] updated .gitignore and cleaned unnecessary files in the repo --- .gitignore | 21 ++ example/.idea/codeStyles/Project.xml | 29 -- example/.idea/libraries/Dart_SDK.xml | 19 - example/.idea/libraries/Flutter_Plugins.xml | 9 - .../.idea/libraries/Flutter_for_Android.xml | 9 - example/.idea/misc.xml | 28 -- example/.idea/modules.xml | 9 - example/.idea/runConfigurations/main_dart.xml | 6 - example/.idea/workspace.xml | 330 ------------------ example/android/gradle.properties | 1 - .../gradle/wrapper/gradle-wrapper.properties | 2 +- example/flutter_plugin_example.iml | 17 - example/flutter_plugin_example_android.iml | 27 -- 13 files changed, 22 insertions(+), 485 deletions(-) delete mode 100644 example/.idea/codeStyles/Project.xml delete mode 100644 example/.idea/libraries/Dart_SDK.xml delete mode 100644 example/.idea/libraries/Flutter_Plugins.xml delete mode 100644 example/.idea/libraries/Flutter_for_Android.xml delete mode 100644 example/.idea/misc.xml delete mode 100644 example/.idea/modules.xml delete mode 100644 example/.idea/runConfigurations/main_dart.xml delete mode 100644 example/.idea/workspace.xml delete mode 100644 example/android/gradle.properties delete mode 100644 example/flutter_plugin_example.iml delete mode 100644 example/flutter_plugin_example_android.iml diff --git a/.gitignore b/.gitignore index 5cb586d1b..b4aadeed4 100644 --- a/.gitignore +++ b/.gitignore @@ -6,9 +6,30 @@ pubspec.lock .example/lib/application_constants.dart +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# Android related +gradle.properties +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +**/ios/Flutter/flutter_export_environment.sh + build/ .idea +example/.flutter-plugins-dependencies example/ios/Frameworks/ example/lib/ui/ +.flutter-plugins-dependencies + .vscode/ diff --git a/example/.idea/codeStyles/Project.xml b/example/.idea/codeStyles/Project.xml deleted file mode 100644 index 30aa626c2..000000000 --- a/example/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/example/.idea/libraries/Dart_SDK.xml b/example/.idea/libraries/Dart_SDK.xml deleted file mode 100644 index 312f57610..000000000 --- a/example/.idea/libraries/Dart_SDK.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/example/.idea/libraries/Flutter_Plugins.xml b/example/.idea/libraries/Flutter_Plugins.xml deleted file mode 100644 index 83a5fa6a3..000000000 --- a/example/.idea/libraries/Flutter_Plugins.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/example/.idea/libraries/Flutter_for_Android.xml b/example/.idea/libraries/Flutter_for_Android.xml deleted file mode 100644 index 29aa45057..000000000 --- a/example/.idea/libraries/Flutter_for_Android.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/example/.idea/misc.xml b/example/.idea/misc.xml deleted file mode 100644 index 32684726d..000000000 --- a/example/.idea/misc.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/example/.idea/modules.xml b/example/.idea/modules.xml deleted file mode 100644 index 68a3e0698..000000000 --- a/example/.idea/modules.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/example/.idea/runConfigurations/main_dart.xml b/example/.idea/runConfigurations/main_dart.xml deleted file mode 100644 index aab7b5cd8..000000000 --- a/example/.idea/runConfigurations/main_dart.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/example/.idea/workspace.xml b/example/.idea/workspace.xml deleted file mode 100644 index 333647f99..000000000 --- a/example/.idea/workspace.xml +++ /dev/null @@ -1,330 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -