flutter_parse_sdk解析

mizuki發表於2019-08-06

入門

安裝依賴到pubspec.yaml

dependencies:  
    parse_server_sdk: ^1.0.22複製程式碼

如果是第一次呼叫,把一下程式碼加入

await Parse().initialize(
        keyApplicationId,
        keyParseServerUrl);複製程式碼

如果您想使用安全儲存或使用Flutter web / desktop SDK,請更改為以下CoreStorage例項,

await Parse().initialize(
  	keyParseApplicationId, 
  	keyParseServerUrl,
    coreStore: await CoreStoreSembastImp.getInstance());複製程式碼

在使用Parse Server例項時也可以新增其他的一些引數

await Parse().initialize(
        keyApplicationId,
        keyParseServerUrl,
        masterKey: keyParseMasterKey, // Required for Back4App and others
        clientKey: keyParseClientKey, // Required for some setups
        debug: true, // 啟用時,會將日誌列印到控制檯
        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複製程式碼


Object(物件)

你可以通過呼叫以下程式碼來儲存一個customer物件

var dietPlan = ParseObject('DietPlan')
	..set('Name', 'Ketogenic')
	..set('Fat', 65);
await dietPlan.save();複製程式碼

驗證物件是否已成功儲存的方法是

var response = await dietPlan.save();
if (response.success) {
   dietPlan = response.results.first;
}複製程式碼

支援的型別:

  • String
  • Double
  • Int
  • Boolean
  • Datetime
  • File(檔案)
  • Geopoint
  • ParseObject/ParseUser (Pointer)
  • Map
  • List (所有型別都支援)

然後,您可以使用下面的方法進行操作:

  • Get
  • GetAll
  • Create
  • Save
  • Query - By object Id
  • Delete
  • Complex queries as shown above
  • Pin
  • Plenty more
  • Counters
  • Array Operators

自定義物件

通過執行以下操作,可以建立自己的ParseObjects或將現有Objects轉換為ParseObjects

class DietPlan extends ParseObject implements ParseCloneable {

  DietPlan() : super(_keyTableName);
  DietPlan.clone(): this();

  /// Looks strangely hacky but due to Flutter not using reflection, we have to
  /// mimic a clone
  @override clone(Map map) => DietPlan.clone()..fromJson(map);

  static const String _keyTableName = 'Diet_Plans';
  static const String keyName = 'Name';
  
  String get name => get<String>(keyName);
  set name(String name) => set<String>(keyName, name);
}複製程式碼

往物件裡面新增新值

下面這個例子先呼叫set去新增變數RandomInt,並且賦值為8

dietPlan.set<int>('RandomInt', 8);
var randomInt = dietPlan.get<int>('RandomInt');複製程式碼

用pins來儲存物件

在物件上呼叫pin()來儲存物件

dietPlan.pin();複製程式碼

然後用fromPin去查詢這個物件

var dietPlan = DietPlan().fromPin('OBJECT ID OF OBJECT');複製程式碼

增加物件中的計數器值

Retrieve it, call

var response = await dietPlan.increment("count", 1);複製程式碼

或者用函式操作

dietPlan.setIncrement('count', 1);
dietPlan.setDecrement('count', 1);
var response = dietPlan.save()複製程式碼

在物件中對陣列進行操作

Retrieve it, call

var response = await dietPlan.add("listKeywords", ["a", "a","d"]);

var response = await dietPlan.addUnique("listKeywords", ["a", "a","d"]);

var response = await dietPlan.remove("listKeywords", ["a"]);複製程式碼

或者用函式操作

dietPlan.setAdd('listKeywords', ['a','a','d']);
dietPlan.setAddUnique('listKeywords', ['a','a','d']);
dietPlan.setRemove('listKeywords', ['a']);
var response = dietPlan.save()複製程式碼

查詢

一旦設定了專案並初始化了例項,就可以通過呼叫

var apiResponse = await ParseObject('ParseTableName').getAll();

if (apiResponse.success){
  for (var testObject in apiResponse.result) {
    print(ApplicationConstants.APP_NAME + ": " + testObject.toString());
  }
}複製程式碼

或者也可以通過objectId去得到一個物件

var dietPlan = await DietPlan().getObject('R5EonpUDWy');

if (dietPlan.success) {
  print(ApplicationConstants.keyAppName + ": " + (dietPlan.result as DietPlan).toString());
} else {
  print(ApplicationConstants.keyAppName + ": " + dietPlan.exception.message);
}複製程式碼

複雜查詢

您可以通過建立複雜的查詢來測試資料庫

var queryBuilder = QueryBuilder<DietPlan>(DietPlan())
  ..startsWith(DietPlan.keyName, "Keto")
  ..greaterThan(DietPlan.keyFat, 64)
  ..lessThan(DietPlan.keyFat, 66)
  ..equals(DietPlan.keyCarbs, 5);

var response = await queryBuilder.query();

if (response.success) {
  print(ApplicationConstants.keyAppName + ": " + ((response.results as List<dynamic>).first as DietPlan).toString());
} else {
  print(ApplicationConstants.keyAppName + ": " + response.exception.message);
}複製程式碼

有以下功能可用

  • Equal(相等)
  • Contains(包含)
  • LessThan(小於)
  • LessThanOrEqualTo(小於或等於)
  • GreaterThan(大於)
  • GreaterThanOrEqualTo(大於或等於)
  • NotEqualTo(不等於)
  • StartsWith()
  • EndsWith
  • Exists(存在)
  • Near(相鄰)
  • WithinMiles
  • WithinKilometers
  • WithinRadians
  • WithinGeoBox
  • Regex
  • Order
  • Limit
  • Skip
  • Ascending
  • Descending
  • Plenty more!

關係查詢

如果要檢索欄位包含與另一個查詢匹配的物件的物件,可以使用whereMatchesQuery。例如,假設您有一個post類和一個comment類,其中每個comment都有一個指向其父類post的指標。您可以通過執行以下操作在帶有images的posts找到comments:

QueryBuilder<ParseObject> queryPost =
    QueryBuilder<ParseObject>(ParseObject('Post'))
      ..whereValueExists('image', true);

QueryBuilder<ParseObject> queryComment =
    QueryBuilder<ParseObject>(ParseObject('Comment'))
      ..whereMatchesQuery('post', queryPost);

var apiResponse = await queryComment.query();複製程式碼

如果要檢索欄位中包含與另一個查詢不匹配的物件的物件,可以使用whereDoesNotMatchQuery條件。假設您有一個post類和一個comment類,其中每個comment都有一個指向其父post的指標。通過執行以下操作,

QueryBuilder<ParseObject> queryPost =
    QueryBuilder<ParseObject>(ParseObject('Post'))
      ..whereValueExists('image', true);

QueryBuilder<ParseObject> queryComment =
    QueryBuilder<ParseObject>(ParseObject('Comment'))
      ..whereDoesNotMatchQuery('post', queryPost);

var apiResponse = await queryComment.query();複製程式碼

計算物件個數

如果您只關心特定玩家玩的遊戲數量:

QueryBuilder<ParseObject> queryPlayers =
    QueryBuilder<ParseObject>(ParseObject('GameScore'))
      ..whereEqualTo('playerName', 'Jonathan Walsh');
var apiResponse = await queryPlayers.count();
if (apiResponse.success && apiResponse.result != null) {
  int countGames = apiResponse.count;
}複製程式碼

實時查詢

此工具允許您訂閱感興趣的QueryBuilder。一旦訂閱,伺服器將在實時建立或更新與QueryBuilder匹配的ParseObject時通知客戶機。

Parse LiveQuery包含兩部分:LiveQuery伺服器和LiveQuery客戶端。為了使用實時查詢,您需要同時設定這兩個查詢。

在此處找到伺服器上的分析伺服器配置指南 docs.parseplatform.org/parse-serve… 這不是本文的一部分。

通過在parse()中輸入引數livequeryurl初始化parse live查詢。初始化:

Parse().initialize(
      keyApplicationId,
      keyParseServerUrl,
      clientKey: keyParseClientKey,
      debug: true,
      liveQueryUrl: keyLiveQueryUrl,
      autoSendSessionId: true);複製程式碼

宣告 LiveQuery:

final LiveQuery liveQuery = LiveQuery();複製程式碼

設定將由LiveQuery監視的QueryBuilder:

QueryBuilder<ParseObject> query =
  QueryBuilder<ParseObject>(ParseObject('TestAPI'))
  ..whereEqualTo('intNumber', 1);複製程式碼

建立訂閱

await liveQuery.subscribe(query);複製程式碼

事件處理

建立事件

liveQuery.on(LiveQueryEvent.create, (value) {
    print('*** CREATE ***: ${DateTime.now().toString()}\n $value ');
    print((value as ParseObject).objectId);
    print((value as ParseObject).updatedAt);
    print((value as ParseObject).createdAt);
    print((value as ParseObject).get('objectId'));
    print((value as ParseObject).get('updatedAt'));
    print((value as ParseObject).get('createdAt'));
});複製程式碼

更新事件

liveQuery.on(LiveQueryEvent.update, (value) {
    print('*** UPDATE ***: ${DateTime.now().toString()}\n $value ');
    print((value as ParseObject).objectId);
    print((value as ParseObject).updatedAt);
    print((value as ParseObject).createdAt);
    print((value as ParseObject).get('objectId'));
    print((value as ParseObject).get('updatedAt'));
    print((value as ParseObject).get('createdAt'));
});複製程式碼

進入事件

liveQuery.on(LiveQueryEvent.enter, (value) {
    print('*** ENTER ***: ${DateTime.now().toString()}\n $value ');
    print((value as ParseObject).objectId);
    print((value as ParseObject).updatedAt);
    print((value as ParseObject).createdAt);
    print((value as ParseObject).get('objectId'));
    print((value as ParseObject).get('updatedAt'));
    print((value as ParseObject).get('createdAt'));
});複製程式碼

離開事件

liveQuery.on(LiveQueryEvent.leave, (value) {
    print('*** LEAVE ***: ${DateTime.now().toString()}\n $value ');
    print((value as ParseObject).objectId);
    print((value as ParseObject).updatedAt);
    print((value as ParseObject).createdAt);
    print((value as ParseObject).get('objectId'));
    print((value as ParseObject).get('updatedAt'));
    print((value as ParseObject).get('createdAt'));
});複製程式碼

銷燬事件

liveQuery.on(LiveQueryEvent.delete, (value) {
    print('*** DELETE ***: ${DateTime.now().toString()}\n $value ');
    print((value as ParseObject).objectId);
    print((value as ParseObject).updatedAt);
    print((value as ParseObject).createdAt);
    print((value as ParseObject).get('objectId'));
    print((value as ParseObject).get('updatedAt'));
    print((value as ParseObject).get('createdAt'));
});複製程式碼

退訂

await liveQuery.unSubscribe();複製程式碼

使用者(User)

您可以使用此SDK正常建立和控制使用者

註冊使用者前要先建立使用者

var user =  ParseUser().create("TestFlutter", "TestPassword123", "TestFlutterSDK@gmail.com");複製程式碼

然後註冊使用者

var response = await user.signUp();
if (response.success) user = response.result;複製程式碼

使用者登入

var response = await user.login();
if (response.success) user = response.result;複製程式碼

使用者登出

var response = await user.logout();
if (response.success) {
    print('User logout');
}複製程式碼

同樣,你可以在使用者登入後管理sessions和tokens。

user = ParseUser.currentUser();複製程式碼

其他的一些使用者操作方法

  • Request Password Reset
  • Verification Email Request
  • Get all users
  • Save
  • Destroy user
  • Queries

ParseACL-物件的安全性

對於任何物件,您可以指定允許哪些使用者讀取物件,以及允許哪些使用者修改物件。為了支援這種安全性,每個物件都有一個訪問控制列表,由ParseAcl類實現。

如果未指定parseAcl(parseUser類除外),則所有物件都設定為public進行讀寫。使用parsacl的最簡單方法是指定一個物件只能由單個使用者讀或寫。要建立這樣的物件,首先必須有一個登入的parseuser。然後,新的parseacl(使用者)生成一個parseacl,限制對該使用者的訪問。與任何其他屬性一樣,儲存物件時更新物件的ACL。

ParseUser user = await ParseUser.currentUser() as ParseUser;
ParseACL parseACL = ParseACL(owner: user);
  
ParseObject parseObject = ParseObject("TestAPI");
...
parseObject.setACL(parseACL);
var apiResponse = await parseObject.save();複製程式碼

還可以根據每個使用者授予許可權。可以使用setreadaccess和setwriteaccess分別向parseacl新增許可權。

ParseUser user = await ParseUser.currentUser() as ParseUser;
ParseACL parseACL = ParseACL();
//grant total access to current user
parseACL.setReadAccess(userId: user.objectId, allowed: true);
parseACL.setWriteAccess(userId: user.objectId, allowed: true);
//grant read access to userId: 'TjRuDjuSAO' 
parseACL.setReadAccess(userId: 'TjRuDjuSAO', allowed: true);
parseACL.setWriteAccess(userId: 'TjRuDjuSAO', allowed: false);

ParseObject parseObject = ParseObject("TestAPI");
...
parseObject.setACL(parseACL);
var apiResponse = await parseObject.save();複製程式碼

還可以使用setpublicreadaccess和setpublicwriteaccess一次授予所有使用者許可權。

ParseACL parseACL = ParseACL();
parseACL.setPublicReadAccess(allowed: true);
parseACL.setPublicWriteAccess(allowed: true);

ParseObject parseObject = ParseObject("TestAPI");
...  
parseObject.setACL(parseACL);
var apiResponse = await parseObject.save();複製程式碼

禁止的操作(例如刪除您沒有寫入許可權的物件)將導致程式碼為101的ParseError:“ObjectNotFound”。出於安全目的,這會阻止客戶機區分哪些物件ID存在但受到保護,以及哪些物件ID根本不存在。

可以使用以下方法檢索物件的ACL列表:

ParseACL parseACL = parseObject.getACL();複製程式碼

配置(Config)

SDK支援Parse Config。可以通過呼叫以下命令從伺服器獲取所有配置的對映:

var response = await ParseConfig().getConfigs();複製程式碼

還有新增配置

ParseConfig().addConfig('TestConfig', 'testing');複製程式碼

雲函式(Cloud Functions)

這個SDK支援所有云函式

執行返回ParseObject型別的雲函式

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);
  }
}複製程式碼

使用引數執行雲函式

final ParseCloudFunction function = ParseCloudFunction('hello');
final Map<String, String> params = <String, String>{'plan': 'paid'};
function.execute(parameters: params);複製程式碼

此庫的其他功能

Main:

  • Installation (View the example application)
  • GeoPoints (View the example application)
  • Files (View the example application)
  • Persistent storage
  • Debug Mode - Logging API calls
  • Manage Session ID's tokens

User:

  • Queries
  • Anonymous (View the example application)
  • 3rd Party Authentication

Objects:

  • Create new object
  • Extend Parse Object and create local objects that can be saved and retreived
  • Queries

作者(Author)

原作者資訊-----This project was authored by Phill Wiggins. You can contact me at phill.wiggins@gmail.com

翻譯來自Mizuki Dragon-----1933908466@qq.com,這個庫我會慢慢翻譯下去的,邊用邊翻譯。

GitHub倉庫位置:github.com/phillwiggin…