mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-09-01 07:24:07 +00:00
try to connect first
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
This commit is contained in:
parent
185ac49de9
commit
1f269ae5b3
3 changed files with 90 additions and 70 deletions
|
|
@ -89,36 +89,40 @@ Future<bool> initBackgroundExecution() async {
|
||||||
final Mutex _keyValueMutex = Mutex();
|
final Mutex _keyValueMutex = Mutex();
|
||||||
|
|
||||||
// ignore: unreachable_from_main
|
// ignore: unreachable_from_main
|
||||||
Future<void> handlePeriodicTask({int lastExecutionInSecondsLimit = 120}) async {
|
Future<bool> backgroundFetch({
|
||||||
final shouldBeExecuted = await exclusiveAccess(
|
int? lastExecutionInSecondsLimit = 120,
|
||||||
lockName: 'periodic_task',
|
}) async {
|
||||||
mutex: _keyValueMutex,
|
if (lastExecutionInSecondsLimit != null) {
|
||||||
action: () async {
|
final shouldBeExecuted = await exclusiveAccess(
|
||||||
final lastExecution = await KeyValueStore.get(
|
lockName: 'periodic_task',
|
||||||
KeyValueKeys.lastPeriodicTaskExecution,
|
mutex: _keyValueMutex,
|
||||||
);
|
action: () async {
|
||||||
if (lastExecution != null && lastExecution.containsKey('timestamp')) {
|
final lastExecution = await KeyValueStore.get(
|
||||||
final lastExecutionTime = lastExecution['timestamp'] as int?;
|
KeyValueKeys.lastPeriodicTaskExecution,
|
||||||
if (lastExecutionTime != null) {
|
);
|
||||||
final lastExecutionDate = DateTime.fromMillisecondsSinceEpoch(
|
if (lastExecution != null && lastExecution.containsKey('timestamp')) {
|
||||||
lastExecutionTime,
|
final lastExecutionTime = lastExecution['timestamp'] as int?;
|
||||||
);
|
if (lastExecutionTime != null) {
|
||||||
if (DateTime.now().difference(lastExecutionDate).inSeconds <
|
final lastExecutionDate = DateTime.fromMillisecondsSinceEpoch(
|
||||||
lastExecutionInSecondsLimit) {
|
lastExecutionTime,
|
||||||
return false;
|
);
|
||||||
|
if (DateTime.now().difference(lastExecutionDate).inSeconds <
|
||||||
|
lastExecutionInSecondsLimit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
await KeyValueStore.put(KeyValueKeys.lastPeriodicTaskExecution, {
|
||||||
await KeyValueStore.put(KeyValueKeys.lastPeriodicTaskExecution, {
|
'timestamp': DateTime.now().millisecondsSinceEpoch,
|
||||||
'timestamp': DateTime.now().millisecondsSinceEpoch,
|
});
|
||||||
});
|
return true;
|
||||||
return true;
|
},
|
||||||
},
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if (!shouldBeExecuted) return;
|
if (!shouldBeExecuted) return false;
|
||||||
|
}
|
||||||
|
|
||||||
Log.info('eu.twonly.periodic_task was called.');
|
Log.info('Periodic task was called.');
|
||||||
AppState.gotMessageFromServer = false;
|
AppState.gotMessageFromServer = false;
|
||||||
|
|
||||||
final stopwatch = Stopwatch()..start();
|
final stopwatch = Stopwatch()..start();
|
||||||
|
|
@ -130,14 +134,16 @@ Future<void> handlePeriodicTask({int lastExecutionInSecondsLimit = 120}) async {
|
||||||
|
|
||||||
if (!await apiService.connect()) {
|
if (!await apiService.connect()) {
|
||||||
Log.info('Could not connect to the api. Returning early.');
|
Log.info('Could not connect to the api. Returning early.');
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!apiService.isAuthenticated) {
|
if (!apiService.isAuthenticated) {
|
||||||
Log.info('Api is not authenticated. Returning early.');
|
Log.info('Api is not authenticated. Returning early.');
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var receiveMessage = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (!AppState.gotMessageFromServer) {
|
while (!AppState.gotMessageFromServer) {
|
||||||
if (stopwatch.elapsed.inSeconds >= 15) {
|
if (stopwatch.elapsed.inSeconds >= 15) {
|
||||||
|
|
@ -148,19 +154,22 @@ Future<void> handlePeriodicTask({int lastExecutionInSecondsLimit = 120}) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AppState.gotMessageFromServer) {
|
if (AppState.gotMessageFromServer) {
|
||||||
|
receiveMessage = true;
|
||||||
Log.info('Received a server message from the server.');
|
Log.info('Received a server message from the server.');
|
||||||
}
|
}
|
||||||
|
|
||||||
await finishStartedPreprocessing();
|
await finishStartedPreprocessing();
|
||||||
|
|
||||||
await Future.delayed(const Duration(milliseconds: 2000));
|
if (lastExecutionInSecondsLimit != null) {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 2000));
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
await apiService.close(() {});
|
await apiService.close(() {});
|
||||||
stopwatch.stop();
|
stopwatch.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.info('eu.twonly.periodic_task finished after ${stopwatch.elapsed}.');
|
Log.info('Periodic task finished after ${stopwatch.elapsed}.');
|
||||||
return;
|
return receiveMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> handleProcessingTask() async {
|
Future<void> handleProcessingTask() async {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||||
|
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
if (isInitialized) {
|
if (isInitialized) {
|
||||||
await handlePeriodicTask(lastExecutionInSecondsLimit: 3);
|
await backgroundFetch(lastExecutionInSecondsLimit: 3);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// make sure every thing run...
|
// make sure every thing run...
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/locator.dart';
|
import 'package:twonly/locator.dart';
|
||||||
import 'package:twonly/src/constants/secure_storage.keys.dart';
|
import 'package:twonly/src/constants/secure_storage.keys.dart';
|
||||||
import 'package:twonly/src/model/protobuf/client/generated/push_notification.pb.dart';
|
import 'package:twonly/src/model/protobuf/client/generated/push_notification.pb.dart';
|
||||||
|
import 'package:twonly/src/services/background/callback_dispatcher.background.dart';
|
||||||
import 'package:twonly/src/services/notifications/background.notifications.dart';
|
import 'package:twonly/src/services/notifications/background.notifications.dart';
|
||||||
import 'package:twonly/src/services/notifications/fcm.background.dart';
|
import 'package:twonly/src/services/notifications/fcm.background.dart';
|
||||||
import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
|
import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
|
||||||
|
|
@ -167,51 +168,61 @@ class FcmNotificationService {
|
||||||
// This is just a workarround until the new Rust decryption is enrolled fully.
|
// This is just a workarround until the new Rust decryption is enrolled fully.
|
||||||
final pushDataString = message.data['push_data'] as String?;
|
final pushDataString = message.data['push_data'] as String?;
|
||||||
if (pushDataString != null) {
|
if (pushDataString != null) {
|
||||||
try {
|
if (apiService.isConnected) {
|
||||||
final pushDataBytes = base64Decode(pushDataString);
|
Log.info('Got FCM message, but API is connected...');
|
||||||
final encryptedPush = EncryptedPushNotification.fromBuffer(
|
} else {
|
||||||
pushDataBytes,
|
Log.info('Trying to connect to the API in the background.');
|
||||||
);
|
|
||||||
final pushUsers = await getPushKeys(
|
if (await backgroundFetch()) {
|
||||||
SecureStorageKeys.receivingPushKeys,
|
return;
|
||||||
);
|
}
|
||||||
for (final pushUser in pushUsers) {
|
|
||||||
for (final pushKey in pushUser.pushKeys) {
|
try {
|
||||||
final decrypted = await tryDecryptMessage(
|
final pushDataBytes = base64Decode(pushDataString);
|
||||||
pushKey.key,
|
final encryptedPush = EncryptedPushNotification.fromBuffer(
|
||||||
encryptedPush,
|
pushDataBytes,
|
||||||
);
|
);
|
||||||
if (decrypted != null) {
|
final pushUsers = await getPushKeys(
|
||||||
if (isUUIDNewer(pushUser.lastMessageId, decrypted.messageId)) {
|
SecureStorageKeys.receivingPushKeys,
|
||||||
|
);
|
||||||
|
for (final pushUser in pushUsers) {
|
||||||
|
for (final pushKey in pushUser.pushKeys) {
|
||||||
|
final decrypted = await tryDecryptMessage(
|
||||||
|
pushKey.key,
|
||||||
|
encryptedPush,
|
||||||
|
);
|
||||||
|
if (decrypted != null) {
|
||||||
|
if (isUUIDNewer(pushUser.lastMessageId, decrypted.messageId)) {
|
||||||
|
Log.info(
|
||||||
|
'Skipping local push notification because message is older than lastMessageId',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Log.info(
|
Log.info(
|
||||||
'Skipping local push notification because message is older than lastMessageId',
|
'Successfully decrypted push_data directly from FCM payload! Showing notification.',
|
||||||
|
);
|
||||||
|
await showLocalPushNotification(
|
||||||
|
pushUser,
|
||||||
|
decrypted,
|
||||||
|
titleSuffix:
|
||||||
|
(userService.isUserCreated &&
|
||||||
|
userService.currentUser.isDeveloper)
|
||||||
|
? ' [d]'
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
unawaited(
|
||||||
|
updateLastMessageId(
|
||||||
|
pushUser.userId.toInt(),
|
||||||
|
decrypted.messageId,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Log.info(
|
|
||||||
'Successfully decrypted push_data directly from FCM payload! Showing notification.',
|
|
||||||
);
|
|
||||||
await showLocalPushNotification(
|
|
||||||
pushUser,
|
|
||||||
decrypted,
|
|
||||||
titleSuffix:
|
|
||||||
(userService.isUserCreated &&
|
|
||||||
userService.currentUser.isDeveloper)
|
|
||||||
? ' [d]'
|
|
||||||
: null,
|
|
||||||
);
|
|
||||||
unawaited(
|
|
||||||
updateLastMessageId(
|
|
||||||
pushUser.userId.toInt(),
|
|
||||||
decrypted.messageId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Log.error('Error handling push_data: $e');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
Log.error('Error handling push_data: $e');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue