Skip to content

feat: Add Parse Flutter SDK documentation #928

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
May 25, 2023
Merged
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
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
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,10 @@ node_modules
# OS X
.DS_Store

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

.jekyll-metadata
1 change: 1 addition & 0 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ apis:
js: https://parseplatform.org/Parse-SDK-JS/api/master/
php: https://parseplatform.org/parse-php-sdk/namespaces/Parse.html
dotnet: https://parseplatform.org/Parse-SDK-dotNET/api/
flutter: https://parseplatform.org/Parse-SDK-Flutter/api/
parse-server: https://parseplatform.org/parse-server/api/

# Build settings
Expand Down
25 changes: 25 additions & 0 deletions _includes/flutter/cloud-code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Cloud Code

The SDK supports calling [Cloud Functions](https://docs.parseplatform.org/cloudcode/guide/#cloud-functions).

Execute a Cloud Function that returns a `ParseObject`:

```dart
final ParseCloudFunction function = ParseCloudFunction('hello');
final ParseResponse result =
await function.executeObjectFunction<ParseObject>();
if (result.success) {
if (result.result is ParseObject) {
final ParseObject parseObject = result.result;
print(parseObject.className);
}
}
```

Execute a Cloud Function with parameters:

```dart
final ParseCloudFunction function = ParseCloudFunction('hello');
final Map<String, String> params = <String, String>{'plan': 'paid'};
function.execute(parameters: params);
```
13 changes: 13 additions & 0 deletions _includes/flutter/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Config

The SDK supports [Parse Config](https://docs.parseplatform.org/cloudcode/guide/#config). A map of config parameters can be retrieved from Parse Server with:

```dart
var response = await ParseConfig().getConfigs();
```

To add a new parameter to Parse Config:

```dart
ParseConfig().addConfig('TestConfig', 'testing');
```
63 changes: 63 additions & 0 deletions _includes/flutter/files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Files

There are three different file classes in this SDK:

- `ParseFileBase` is an abstract class and is the foundation of every file class that can be handled by the SDK.
- `ParseFile` extends `ParseFileBase` and is by default used as the file class on every platform but web. This class uses a `File` from `dart:io` for storing the raw file. The class was formerly the only file class in the SDK.
- `ParseWebFile` is the equivalent of `ParseFile` used for Flutter Web. This class uses a `Uint8List` for storing the raw file data.

The classes above are used by default to represent files, but you can also build your own class extending `ParseFileBase` and provide a custom `ParseFileConstructor` similar to the `SubClasses`.

Have a look at the example application for a small (non web) example.

When uploading or downloading a file, you can use the `progressCallback` parameter to track the progress of the HTTP request.

The following is an example for showing an image from a `ParseFileBase`:

```dart
Widget buildImage(ParseFileBase image){
return FutureBuilder<ParseFileBase>(
future: image.download(),
builder: (BuildContext context,
AsyncSnapshot<ParseFileBase> snapshot) {
if (snapshot.hasData) {
if (kIsWeb) {
return Image.memory((snapshot.data as ParseWebFile).file);
} else {
return Image.file((snapshot.data as ParseFile).file);
}
} else {
return CircularProgressIndicator();
}
},
);
}
```

A short example for storing a selected image:

```dart
// Libraries: image_picker (https://pub.dev/packages/image_picker), image_picker_for_web (https://pub.dev/packages/image_picker_for_web)
PickedFile pickedFile = await ImagePicker().getImage(source: ImageSource.gallery);

ParseFileBase parseFile;

if (kIsWeb) {
// Get data from selected file as an Uint8List
ParseWebFile file = ParseWebFile(null, name: null, url: pickedFile.path);
await file.download();
parseFile = ParseWebFile(file.file, name: file.name);
} else {
parseFile = ParseFile(File(pickedFile.path));
}

someParseObject.set("image", parseFile);
// Save ParseObject and its children like the ParseFileBase
await someParseObject.save();
```

Example for using the progress callback:

```dart
file.upload(progressCallback: (int count, int total) => print("$count of $total"));
```
74 changes: 74 additions & 0 deletions _includes/flutter/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Getting Started

- To install the Parse Dart SDK add it to your app as a dependency via the [pub.dev](https://pub.dev/packages/parse_server_sdk/install) registry.
- To install the Parse Flutter SDK add it to your app as a dependency via the [pub.dev](https://pub.dev/packages/parse_server_sdk_flutter/install) registry.

Once you have the SDK added as a dependency, initialize the SDK as early as possible in your application (e.g. in your application class) like this:

```dart
await Parse().initialize(
keyApplicationId,
keyParseServerUrl,
);
```

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. `CoreStoreSembastImp` does not encrypt the data on the web and Web is not safe anyway. Encrypt fields manually as needed.

```dart
await Parse().initialize(
keyParseApplicationId,
keyParseServerUrl,
coreStore: await CoreStoreSembastImp.getInstance("/data"));
```

It's possible to add other parameters to work with your instance of Parse Server:

```dart
await Parse().initialize(
keyApplicationId,
keyParseServerUrl,
clientKey: keyParseClientKey, // Required for some setups
debug: true, // When enabled, prints logs to console
liveQueryUrl: keyLiveQueryUrl, // Required if using LiveQuery
autoSendSessionId: true, // Required for authentication and ACL
securityContext: securityContext, // Again, required for some setups
coreStore: CoreStoreMemoryImp()); // Non persistent mode (default): Sdk will store everything in memory instead of using Sembast as an internal DB.
```

⚠️ The master key should only be used in safe environments and never on client side. Using this package on a server should be fine.

### Early Web Support

Due to Cross-Origin Resource Sharing (CORS) restrictions, web support requires adding `X-Parse-Installation-Id` as an allowed header in the Parse Server configuration:

- When running directly via docker, set the env var `PARSE_SERVER_ALLOW_HEADERS=X-Parse-Installation-Id`.
- When running via express, set the [Parse Server option](https://parseplatform.org/parse-server/api/master/ParseServerOptions.html) `allowHeaders: ['X-Parse-Installation-Id']`.

### Desktop Support (macOS)

The security entitlements posed by the macOS framework require that your app is granted permission to open outgoing network connections, so that the Parse Flutter SDK can communicate with Parse Server. To grant this permission, add the following code:

```swift
<key>com.apple.security.network.client</key>
<true/>
```

to the following files:

```
/macOS/Runner/Release.entitlements
/macOS/Runner/DebugProfile.entitlements
```

### Network client

By default, this SDK uses the `ParseHTTPClient`. Another option is use `ParseDioClient`. This client supports the most features (for example a progress callback at the file upload), but a benchmark has shown that dio is slower than http on web.

If you want to use the `ParseDioClient`, which uses the dio network library, you can provide a custom `ParseClientCreator` at the initialization of the SDK:

```dart
await Parse().initialize(
//...
clientCreator: ({bool? sendSessionId, SecurityContext? securityContext}) => ParseDioClient(sendSessionId: sendSessionId, securityContext: securityContext),
);
```
Loading