Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Bugfix #245

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8c7f286
Merged v1.0.22
phillwiggins Jun 23, 2019
ea77ae6
Updated versioning
phillwiggins Jun 23, 2019
3bf9047
Hot-fix (#209)
yulingtianxia Jul 2, 2019
b2ae8ec
v1.0.23 - Updated dependencies
phillwiggins Jul 9, 2019
8644610
same fix for version 1.0.23 (#218)
zenz Jul 11, 2019
b8d8da3
v1.0.23 - Updated dependencies
phillwiggins Jul 11, 2019
0131c33
v1.0.23 - Added unset
phillwiggins Jul 11, 2019
4cd0a3e
v1.0.23 - Fixed unset
phillwiggins Jul 11, 2019
7d0e080
v1.0.23 - Added Facebook login helper
phillwiggins Jul 13, 2019
0a4e8dc
v1.0.23 - Added Facebook login helper
phillwiggins Jul 13, 2019
3b3ab34
v1.0.23 - Added Facebook README details
phillwiggins Jul 13, 2019
789bdaf
v1.0.23 - Added authData object
phillwiggins Jul 13, 2019
2ed183c
v1.0.23 - Added authData object
phillwiggins Jul 13, 2019
3f871b0
v1.0.23 - Corrected AuthData type
phillwiggins Jul 13, 2019
33c4de1
Support keysToReturn limiter in livequery (#222)
rostopira Jul 13, 2019
efd0a0f
Fix crash on Flutter Web (#223)
rostopira Jul 19, 2019
beb98fe
add distinct function (#225)
hellokidder Jul 19, 2019
0cffb99
fix(LiveQuery): Session token null when subscribing (#228)
douglasmuraoka Jul 25, 2019
d857c3a
Allow adding additional columns to ParseUser through the set call (#232)
VigneshPasupathy Jul 30, 2019
79d6a4a
ParseFile should NOT extends ParseObject. (#233)
yulingtianxia Aug 1, 2019
931fdd8
Fix a stupid mistake. (#234)
yulingtianxia Aug 1, 2019
026efe9
Fix ACL save (#226) (#236)
manhhavu Aug 2, 2019
d351caf
The method of setAdd, setRemove, setAddAll, setRemoveAll, Increment, …
Aug 7, 2019
d2b8cf3
remove the commented out code.
Aug 7, 2019
5a65098
Fix OrderBy multiple columns #241
Aug 9, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.DS_Store
.dart_tool/

.history
.packages
.pub/
pubspec.lock
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
## 1.0.23

## 1.0.22
Added dirty children
Added option of sembast or share_preferences

## 1.0.21
LiveQuery fix
Expand Down
128 changes: 70 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
![enter image description here](https://upload.wikimedia.org/wikipedia/commons/1/17/Google-flutter-logo.png)
![enter image description here](https://i2.wp.com/blog.openshift.com/wp-content/uploads/parse-server-logo-1.png?fit=200%2C200&ssl=1&resize=350%2C200)

[![Build Status](https://travis-ci.org/phillwiggins/flutter_parse_sdk.svg?branch=master)](https://travis-ci.org/phillwiggins/flutter_parse_sdk)
![Parse Logo](https://upload.wikimedia.org/wikipedia/commons/1/17/Google-flutter-logo.png)![Flutter Logo](https://i2.wp.com/blog.openshift.com/wp-content/uploads/parse-server-logo-1.png?fit=200%2C200&ssl=1&resize=350%2C200)

## Parse For Flutter!
Hi, this is a Flutter plugin that allows communication with a Parse Server, (https://parseplatform.org) either hosted on your own server or another, like (http://Back4App.com).
Expand All @@ -15,39 +13,40 @@ Want to get involved? Join our Slack channel and help out! (http://flutter-parse
To install, either add to your pubspec.yaml
```yml
dependencies:
parse_server_sdk: ^1.0.22
parse_server_sdk: ^1.0.23
```
or clone this repository and add to your project. As this is an early development with multiple contributors, it is probably best to download/clone and keep updating as an when a new feature is added.


Once you have the library added to your project, upon first call to your app (Similar to what your application class would be) add the following...

```dart
await Parse().initialize(
ApplicationConstants.keyApplicationId,
ApplicationConstants.keyParseServerUrl);
await Parse().initialize(
keyApplicationId,
keyParseServerUrl);
```
if you want to use secure storage also that's allow using sdk on desktop application

If you want to use secure storage or use the Flutter web/desktop SDK, please change to the below instance of CoreStorage as it has no dependencies on Flutter.
```dart

await Parse().initialize(keyParseApplicationId, keyParseServerUrl,
masterKey: keyParseMasterKey,
debug: true,
coreStore: await CoreStoreSembastImp.getInstance());
await Parse().initialize(
keyParseApplicationId,
keyParseServerUrl,
coreStore: await CoreStoreSembastImp.getInstance());
```
It's possible to add other params, such as ...
It's possible to add other parameters to work with your instance of Parse Server:-

```dart
await Parse().initialize(
ApplicationConstants.keyApplicationId,
ApplicationConstants.keyParseServerUrl,
masterKey: ApplicationConstants.keyParseMasterKey,
clientKey: ApplicationConstants.keyParseClientKey,
debug: true,
liveQueryUrl: ApplicationConstants.keyLiveQueryUrl,
autoSendSessionId: true,
securityContext: securityContext,
coreStore: await CoreStoreSharedPrefsImp.getInstance());
keyApplicationId,
keyParseServerUrl,
masterKey: keyParseMasterKey, // Required for Back4App and others
clientKey: keyParseClientKey, // Required for some setups
debug: true, // When enabled, prints logs to console
liveQueryUrl: keyLiveQueryUrl, // Required if using LiveQuery
autoSendSessionId: true, // Some confurations require this to be true
securityContext: securityContext, // Again, required for some setups
coreStore: await CoreStoreSharedPrefsImp.getInstance()); // Will use SharedPreferences instead of Sembast as an internal DB
```

## Objects
Expand All @@ -56,13 +55,13 @@ You can create custom objects by calling:
var dietPlan = ParseObject('DietPlan')
..set('Name', 'Ketogenic')
..set('Fat', 65);
await dietPlan.save()
await dietPlan.save();
```
Verify that the object has been successfully saved using
```dart
var response = await dietPlan.save();
if (response.success) {
dietPlan = response.result;
dietPlan = response.results.first;
}
```
Types supported:
Expand Down Expand Up @@ -134,14 +133,6 @@ and to retrieve it
var dietPlan = DietPlan().fromPin('OBJECT ID OF OBJECT');
```

## Storage
We now have 2 types of storage, secure and unsecure. We currently rely on 2 third party options:

* SharedPreferences
* Sembast

Sembast offers secured storage, whilst SharePreferences wraps NSUserDefaults (on iOS) and SharedPreferences (on Android).

## Increment Counter values in objects
Retrieve it, call

Expand Down Expand Up @@ -172,9 +163,9 @@ var response = await dietPlan.remove("listKeywords", ["a"]);
or using with save function

```dart
dietPlan.setAddAll('listKeywords', ['a','a','d']);
dietPlan.setAddAllUnique('listKeywords', ['a','a','d']);
dietPlan.setRemoveAll('listKeywords', ['a']);
dietPlan.setAdd('listKeywords', ['a','a','d']);
dietPlan.setAddUnique('listKeywords', ['a','a','d']);
dietPlan.setRemove('listKeywords', ['a']);
var response = dietPlan.save()
```

Expand Down Expand Up @@ -214,7 +205,7 @@ var queryBuilder = QueryBuilder<DietPlan>(DietPlan())
var response = await queryBuilder.query();

if (response.success) {
print(ApplicationConstants.keyAppName + ": " + ((response.result as List<dynamic>).first as DietPlan).toString());
print(ApplicationConstants.keyAppName + ": " + ((response.results as List<dynamic>).first as DietPlan).toString());
} else {
print(ApplicationConstants.keyAppName + ": " + response.exception.message);
}
Expand Down Expand Up @@ -304,11 +295,11 @@ The Parse Server configuration guide on the server is found here https://docs.pa
Initialize the Parse Live Query by entering the parameter liveQueryUrl in Parse().initialize:
```dart
Parse().initialize(
ApplicationConstants.keyApplicationId,
ApplicationConstants.keyParseServerUrl,
clientKey: ApplicationConstants.keyParseClientKey,
keyApplicationId,
keyParseServerUrl,
clientKey: keyParseClientKey,
debug: true,
liveQueryUrl: ApplicationConstants.keyLiveQueryUrl,
liveQueryUrl: keyLiveQueryUrl,
autoSendSessionId: true);
```

Expand Down Expand Up @@ -450,13 +441,52 @@ Also, once logged in you can manage sessions tokens. This feature can be called
```dart
user = ParseUser.currentUser();
```

To add additional columns to the user:
```dart
var user = ParseUser("TestFlutter", "TestPassword123", "TestFlutterSDK@gmail.com")
..set("userLocation", "FlutterLand");
```

Other user features are:-
* Request Password Reset
* Verification Email Request
* Get all users
* Save
* Destroy user
* Queries

## Facebook, OAuth and 3rd Party Login/User

Usually, each provider will provide their own library for logins, but the loginWith method on ParseUser accepts a name of provider, then a Map<String, dynamic> with the authentication details required.
For Facebook and the example below, we used the library provided at https://pub.dev/packages/flutter_facebook_login

```
Future<void> goToFacebookLogin() async {
final FacebookLogin facebookLogin = FacebookLogin();
final FacebookLoginResult result = await facebookLogin.logInWithReadPermissions(['email']);

switch (result.status) {
case FacebookLoginStatus.loggedIn:
final ParseResponse response = await ParseUser.loginWith(
'facebook',
facebook(result.accessToken.token,
result.accessToken.userId,
result.accessToken.expires));

if (response.success) {
// User is logged in, test with ParseUser.currentUser()
}
break;
case FacebookLoginStatus.cancelledByUser:
// User cancelled
break;
case FacebookLoginStatus.error:
// Error
break;
}
}
```

## Security for Objects - ParseACL
For any object, you can specify which users are allowed to read the object, and which users are allowed to modify an object.
Expand Down Expand Up @@ -548,21 +578,6 @@ final Map<String, String> params = <String, String>{'plan': 'paid'};
function.execute(parameters: params);
```

## Relation
The SDK supports Relation.

To Retrive a relation instance for user, call:
```dart
final relation = user.getRelation('dietPlans');
```

and then you can add a relation to the passed in object.

```dart
relation.add(dietPlan);
final result = await user.save();
```

## Other Features of this library
Main:
* Installation (View the example application)
Expand All @@ -584,6 +599,3 @@ Objects:

## Author:-
This project was authored by Phill Wiggins. You can contact me at phill.wiggins@gmail.com
<!--stackedit_data:
eyJoaXN0b3J5IjpbLTU4MDA4MDUwNCw3MTg2NTA0MjBdfQ==
-->
8 changes: 4 additions & 4 deletions example/lib/domain/constants/application_constants.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const String keyApplicationName = 'BodyCal';
const String keyParseApplicationId = 'bodycaldb';
const String keyParseMasterKey = '343gf35g4t6hev445f4t5f45g45d';
const String keyParseServerUrl = 'http://45.76.129.16:1338/parse/';
const String keyApplicationName = '';
const String keyParseApplicationId = '';
const String keyParseMasterKey = '';
const String keyParseServerUrl = '';
10 changes: 7 additions & 3 deletions lib/parse_server_sdk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ part 'src/utils/parse_logger.dart';

part 'src/utils/parse_utils.dart';

part 'src/utils/parse_login_helpers.dart';

part 'src/objects/parse_merge.dart';

class Parse {
ParseCoreData data;
bool _hasBeenInitialized = false;
Expand All @@ -114,8 +118,8 @@ class Parse {
String masterKey,
String sessionId,
bool autoSendSessionId,
SecurityContext securityContext,
CoreStore coreStore}) async {
SecurityContext securityContext,
CoreStore coreStore}) async {
final String url = removeTrailingSlash(serverUrl);

await ParseCoreData.init(appId, url,
Expand Down Expand Up @@ -145,7 +149,7 @@ class Parse {
final ParseHTTPClient _client = client ??
ParseHTTPClient(
sendSessionId:
sendSessionIdByDefault ?? ParseCoreData().autoSendSessionId,
sendSessionIdByDefault ?? ParseCoreData().autoSendSessionId,
securityContext: ParseCoreData().securityContext);

const String className = 'parseBase';
Expand Down
4 changes: 3 additions & 1 deletion lib/src/base/parse_constants.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
part of flutter_parse_sdk;

// Library
const String keySdkVersion = '1.0.22';
const String keySdkVersion = '1.0.23';
const String keyLibraryName = 'Flutter Parse SDK';

// End Points
Expand All @@ -15,6 +15,7 @@ const String keyEndPointVerificationEmail = '/verificationEmailRequest';
const String keyEndPointRequestPasswordReset = '/requestPasswordReset';
const String keyEndPointClasses = '/classes/';
const String keyEndPointHealth = '/health';
const String keyEndPointAggregate = '/aggregate/';

// ParseObject variables
const String keyVarClassName = 'className';
Expand All @@ -25,6 +26,7 @@ const String keyVarUsername = 'username';
const String keyVarEmail = 'email';
const String keyVarPassword = 'password';
const String keyVarSessionToken = 'sessionToken';
const String keyVarAuthData = 'authData';
const String keyVarAcl = 'ACL';
const String keyVarName = 'name';
const String keyVarURL = 'url';
Expand Down
1 change: 1 addition & 0 deletions lib/src/enums/parse_enum_api_rq.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ enum ParseApiRQ {
healthCheck,
get,
getAll,
unset,
create,
save,
query,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/network/parse_http_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class ParseHTTPClient extends BaseClient {
: _sendSessionId = sendSessionId,
_client = securityContext != null
? IOClient(HttpClient(context: securityContext))
: IOClient();
: Client();

final Client _client;
final bool _sendSessionId;
Expand Down
21 changes: 14 additions & 7 deletions lib/src/network/parse_live_query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class LiveQuery {
securityContext: ParseCoreData().securityContext);

_debug = isDebugEnabled(objectLevelDebug: debug);
_sendSessionId = autoSendSessionId ?? ParseCoreData().autoSendSessionId ?? true;
_sendSessionId =
autoSendSessionId ?? ParseCoreData().autoSendSessionId ?? true;
}

WebSocket _webSocket;
Expand Down Expand Up @@ -40,7 +41,6 @@ class LiveQuery {

// ignore: always_specify_types
Future subscribe(QueryBuilder query) async {

String _liveQueryURL = _client.data.liveQueryURL;
if (_liveQueryURL.contains('https')) {
_liveQueryURL = _liveQueryURL.replaceAll('https', 'wss');
Expand All @@ -49,6 +49,7 @@ class LiveQuery {
}

final String _className = query.object.parseClassName;
final keysToReturn = query.limiters['keys']?.split(',');
query.limiters.clear(); //Remove limits in LiveQuery
final String _where = query._buildQuery().replaceAll('where=', '');

Expand Down Expand Up @@ -101,7 +102,7 @@ class LiveQuery {
if (_debug) {
print('$_printConstLiveQuery: Done');
}
}, onError: (Error error) {
}, onError: (Object error) {
if (_debug) {
print(
'$_printConstLiveQuery: Error: ${error.runtimeType.toString()}');
Expand All @@ -114,13 +115,17 @@ class LiveQuery {
//It should be the first message sent from a client after the WebSocket connection is established.
_connectMessage = <String, String>{
'op': 'connect',
'applicationId': _client.data.applicationId,
'clientKey': _client.data.clientKey ?? ''
'applicationId': _client.data.applicationId
};
if (_sendSessionId) {
if (_sendSessionId && _client.data.sessionId != null) {
_connectMessage['sessionToken'] = _client.data.sessionId;
}

if (_client.data.clientKey != null)
_connectMessage['clientKey'] = _client.data.clientKey;
if (_client.data.masterKey != null)
_connectMessage['masterKey'] = _client.data.masterKey;

if (_debug) {
print('$_printConstLiveQuery: ConnectMessage: $_connectMessage');
}
Expand All @@ -134,9 +139,11 @@ class LiveQuery {
'query': <String, dynamic>{
'className': _className,
'where': _whereMap,
if (keysToReturn != null && keysToReturn.length > 0)
'fields': keysToReturn
}
};
if (_sendSessionId) {
if (_sendSessionId && _client.data.sessionId != null) {
_subscribeMessage['sessionToken'] = _client.data.sessionId;
}

Expand Down
Loading