From c5f08f6c837a340fbaf6100345e35290c3fb7c5a Mon Sep 17 00:00:00 2001 From: Mohammad Bagher Fakouri Date: Sat, 11 Nov 2023 18:07:24 +0330 Subject: [PATCH] feat: Add `installationId` in LiveQuery connect (#976) --- packages/dart/CHANGELOG.md | 6 ++ .../dart/lib/src/base/parse_constants.dart | 2 +- .../lib/src/network/parse_live_query.dart | 26 ++++++-- packages/dart/pubspec.yaml | 2 +- .../src/network/parse_live_query_test.dart | 63 +++++++++++++++++++ packages/dart/test/test_utils.dart | 3 +- 6 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 packages/dart/test/src/network/parse_live_query_test.dart diff --git a/packages/dart/CHANGELOG.md b/packages/dart/CHANGELOG.md index 4fb53def1..748d734b1 100644 --- a/packages/dart/CHANGELOG.md +++ b/packages/dart/CHANGELOG.md @@ -1,3 +1,9 @@ +## [6.3.0](https://github.com/parse-community/Parse-SDK-Flutter/compare/dart-6.2.0...dart-6.3.0) (2023-11-11) + +### Features + +* Add `installationId` in LiveQuery `connect` ([#976](https://github.com/parse-community/Parse-SDK-Flutter/pull/976)) + ## [6.2.0](https://github.com/parse-community/Parse-SDK-Flutter/compare/dart-6.1.0...dart-6.2.0) (2023-10-18) ### Features diff --git a/packages/dart/lib/src/base/parse_constants.dart b/packages/dart/lib/src/base/parse_constants.dart index b7768b217..f0170438d 100644 --- a/packages/dart/lib/src/base/parse_constants.dart +++ b/packages/dart/lib/src/base/parse_constants.dart @@ -1,7 +1,7 @@ part of flutter_parse_sdk; // Library -const String keySdkVersion = '6.2.0'; +const String keySdkVersion = '6.3.0'; const String keyLibraryName = 'Flutter Parse SDK'; // End Points diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index 0f94861f3..1841732e3 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -22,6 +22,7 @@ class Subscription { 'error' ]; Map eventCallbacks = {}; + void on(LiveQueryEvent op, Function callback) { eventCallbacks[_liveQueryEvent[op.index]] = callback; } @@ -140,8 +141,10 @@ class LiveQueryClient { reconnectingController = LiveQueryReconnectingController( () => reconnect(userInitialized: false), getClientEventStream, _debug); } + static LiveQueryClient get instance => _getInstance(); static LiveQueryClient? _instance; + static LiveQueryClient _getInstance({bool? debug, bool? autoSendSessionId}) { String? liveQueryURL = ParseCoreData().liveQueryURL; if (liveQueryURL == null) { @@ -174,13 +177,14 @@ class LiveQueryClient { bool _connecting = false; late StreamController _clientEventStreamController; late Stream _clientEventStream; + StreamController? chanelStream; late LiveQueryReconnectingController reconnectingController; final Map _requestSubscription = {}; Future reconnect({bool userInitialized = false}) async { await _connect(userInitialized: userInitialized); - _connectLiveQuery(); + await _connectLiveQuery(); } int readyState() { @@ -286,6 +290,8 @@ class LiveQueryClient { _channel = channel; channel.stream.listen((dynamic message) { _handleMessage(message); + + chanelStream?.sink.add(message); }, onDone: () { _clientEventStreamController.sink .add(LiveQueryClientEvent.disconnected); @@ -315,7 +321,7 @@ class LiveQueryClient { } } - void _connectLiveQuery() { + Future _connectLiveQuery() async { WebSocketChannel? channel = _channel; if (channel == null) { return; @@ -333,10 +339,22 @@ class LiveQueryClient { connectMessage['sessionToken'] = sessionId; } } + String? clientKey = ParseCoreData().clientKey; + if (clientKey != null) { + connectMessage['clientKey'] = clientKey; + } + String? masterKey = ParseCoreData().masterKey; - if (clientKey != null) connectMessage['clientKey'] = clientKey; - if (masterKey != null) connectMessage['masterKey'] = masterKey; + if (masterKey != null) { + connectMessage['masterKey'] = masterKey; + } + + String? parseInstallation = + (await ParseInstallation.currentInstallation()).installationId; + if (parseInstallation != null) { + connectMessage['installationId'] = parseInstallation; + } if (_debug) { print('$_printConstLiveQuery: ConnectMessage: $connectMessage'); diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 87b45f563..c972690c3 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,6 +1,6 @@ name: parse_server_sdk description: The Dart SDK to connect to Parse Server. Build your apps faster with Parse Platform, the complete application stack. -version: 6.2.0 +version: 6.3.0 homepage: https://parseplatform.org repository: https://github.com/parse-community/Parse-SDK-Flutter issue_tracker: https://github.com/parse-community/Parse-SDK-Flutter/issues diff --git a/packages/dart/test/src/network/parse_live_query_test.dart b/packages/dart/test/src/network/parse_live_query_test.dart new file mode 100644 index 000000000..a7dc928e8 --- /dev/null +++ b/packages/dart/test/src/network/parse_live_query_test.dart @@ -0,0 +1,63 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:parse_server_sdk/parse_server_sdk.dart'; +import 'package:test/test.dart'; + +import '../../test_utils.dart'; + +void main() { + setUpAll(() async { + // Create a fake server + final channel = spawnHybridCode(r''' + import 'dart:io'; + import 'package:stream_channel/stream_channel.dart'; + + hybridMain(StreamChannel channel) async { + var server = await HttpServer.bind('localhost', 0); + server.transform(WebSocketTransformer()).listen((webSocket) { + webSocket.listen((request) { + webSocket.add(request); + }); + }); + channel.sink.add(server.port); + } + '''); + + // Get port server + int port = await channel.stream.first as int; + await initializeParse(liveQueryUrl: 'http://localhost:$port'); + }); + + test('should exist installationId in connect LiveQuery', () async { + // arrange + QueryBuilder query = + QueryBuilder(ParseObject('Test')); + + // Set installationId + ParseInstallation parseInstallation = ParseInstallation(); + parseInstallation.set(keyInstallationId, "1234"); + final String objectJson = json.encode(parseInstallation.toJson(full: true)); + await ParseCoreData() + .getStore() + .setString(keyParseStoreInstallation, objectJson); + + // Initialize LiveQuery + final LiveQuery liveQuery = LiveQuery(); + liveQuery.client.chanelStream = StreamController(); + + // act + await liveQuery.client.reconnect(); + await liveQuery.client.subscribe(query); + + // assert + liveQuery.client.chanelStream?.stream.listen((event) { + if (event.contains('connect')) { + expect(true, event.contains('1234')); + } + }); + + // 10 millisecond hold for stream + await Future.delayed(Duration(milliseconds: 10)); + }); +} diff --git a/packages/dart/test/test_utils.dart b/packages/dart/test/test_utils.dart index 2f138551a..fbf7ee43b 100644 --- a/packages/dart/test/test_utils.dart +++ b/packages/dart/test/test_utils.dart @@ -3,10 +3,11 @@ import 'package:test/test.dart'; const serverUrl = 'https://example.com'; -Future initializeParse() async { +Future initializeParse({String? liveQueryUrl}) async { await Parse().initialize( 'appId', serverUrl, + liveQueryUrl: liveQueryUrl, debug: true, // to prevent automatic detection fileDirectory: 'someDirectory',