2021-10-12 09:12:28 +00:00
|
|
|
import 'package:firebase_core/firebase_core.dart';
|
2022-02-04 05:31:07 +00:00
|
|
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
2021-10-12 09:12:28 +00:00
|
|
|
import 'package:logging/logging.dart';
|
2021-11-10 19:14:25 +00:00
|
|
|
import 'package:photos/core/configuration.dart';
|
2021-11-11 18:58:44 +00:00
|
|
|
import 'package:photos/core/constants.dart';
|
2021-11-10 19:14:25 +00:00
|
|
|
import 'package:photos/core/event_bus.dart';
|
2021-11-10 19:19:33 +00:00
|
|
|
import 'package:photos/core/network.dart';
|
2021-11-10 19:14:25 +00:00
|
|
|
import 'package:photos/events/signed_in_event.dart';
|
2021-10-12 09:36:22 +00:00
|
|
|
import 'package:photos/services/sync_service.dart';
|
2021-11-10 19:14:25 +00:00
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
2021-10-12 09:12:28 +00:00
|
|
|
|
|
|
|
class PushService {
|
2021-11-11 18:58:44 +00:00
|
|
|
static const kFCMPushToken = "fcm_push_token";
|
|
|
|
static const kLastFCMTokenUpdationTime = "fcm_push_token_updation_time";
|
2022-09-20 11:53:32 +00:00
|
|
|
static const kFCMTokenUpdationIntervalInMicroSeconds = 30 * microSecondsInDay;
|
2021-11-15 14:21:43 +00:00
|
|
|
static const kPushAction = "action";
|
|
|
|
static const kSync = "sync";
|
2021-11-10 19:19:33 +00:00
|
|
|
|
2021-10-12 09:12:28 +00:00
|
|
|
static final PushService instance = PushService._privateConstructor();
|
|
|
|
static final _logger = Logger("PushService");
|
|
|
|
|
2022-12-30 08:13:19 +00:00
|
|
|
late SharedPreferences _prefs;
|
2021-11-10 19:14:25 +00:00
|
|
|
|
2021-10-12 09:12:28 +00:00
|
|
|
PushService._privateConstructor();
|
|
|
|
|
|
|
|
Future<void> init() async {
|
2021-11-11 18:58:44 +00:00
|
|
|
_prefs = await SharedPreferences.getInstance();
|
2021-10-12 09:12:28 +00:00
|
|
|
await Firebase.initializeApp();
|
|
|
|
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
|
2021-11-15 14:16:15 +00:00
|
|
|
_logger.info("Got a message whilst in the foreground!");
|
2021-11-25 10:34:30 +00:00
|
|
|
_handleForegroundPushMessage(message);
|
2021-10-12 09:12:28 +00:00
|
|
|
});
|
2022-01-07 07:33:31 +00:00
|
|
|
try {
|
|
|
|
if (Configuration.instance.hasConfiguredAccount()) {
|
|
|
|
await _configurePushToken();
|
|
|
|
} else {
|
|
|
|
Bus.instance.on<SignedInEvent>().listen((_) async {
|
|
|
|
_configurePushToken();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} catch (e, s) {
|
|
|
|
_logger.severe("Could not configure push token", e, s);
|
2021-11-10 19:14:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> _configurePushToken() async {
|
2022-12-30 08:13:19 +00:00
|
|
|
final String? fcmToken = await FirebaseMessaging.instance.getToken();
|
2021-11-14 14:52:05 +00:00
|
|
|
final shouldForceRefreshServerToken =
|
|
|
|
DateTime.now().microsecondsSinceEpoch -
|
|
|
|
(_prefs.getInt(kLastFCMTokenUpdationTime) ?? 0) >
|
|
|
|
kFCMTokenUpdationIntervalInMicroSeconds;
|
2022-12-30 08:20:53 +00:00
|
|
|
if (fcmToken != null &&
|
|
|
|
(_prefs.getString(kFCMPushToken) != fcmToken ||
|
|
|
|
shouldForceRefreshServerToken)) {
|
2022-12-30 08:13:19 +00:00
|
|
|
final String? apnsToken = await FirebaseMessaging.instance.getAPNSToken();
|
2021-11-11 18:58:44 +00:00
|
|
|
try {
|
2021-11-14 14:52:05 +00:00
|
|
|
_logger.info("Updating token on server");
|
2021-11-11 18:58:44 +00:00
|
|
|
await _setPushTokenOnServer(fcmToken, apnsToken);
|
2022-12-30 08:20:53 +00:00
|
|
|
await _prefs.setString(kFCMPushToken, fcmToken);
|
|
|
|
await _prefs.setInt(
|
|
|
|
kLastFCMTokenUpdationTime,
|
|
|
|
DateTime.now().microsecondsSinceEpoch,
|
|
|
|
);
|
2021-11-11 18:58:44 +00:00
|
|
|
_logger.info("Push token updated on server");
|
|
|
|
} catch (e) {
|
|
|
|
_logger.severe("Could not set push token", e, StackTrace.current);
|
|
|
|
}
|
2021-11-14 14:52:05 +00:00
|
|
|
} else {
|
|
|
|
_logger.info("Skipping token update");
|
2021-11-10 19:14:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-30 08:13:19 +00:00
|
|
|
Future<void> _setPushTokenOnServer(
|
2022-12-30 08:20:53 +00:00
|
|
|
String fcmToken,
|
2022-12-30 08:20:13 +00:00
|
|
|
String? apnsToken,
|
|
|
|
) async {
|
2022-10-14 15:03:55 +00:00
|
|
|
await Network.instance.enteDio.post(
|
|
|
|
"/push/token",
|
2021-11-11 18:58:44 +00:00
|
|
|
data: {
|
|
|
|
"fcmToken": fcmToken,
|
|
|
|
"apnsToken": apnsToken,
|
|
|
|
},
|
|
|
|
);
|
2021-10-12 09:12:28 +00:00
|
|
|
}
|
|
|
|
|
2021-11-25 10:34:30 +00:00
|
|
|
void _handleForegroundPushMessage(RemoteMessage message) {
|
2021-11-15 14:16:15 +00:00
|
|
|
_logger.info("Message data: ${message.data}");
|
2021-10-13 05:24:49 +00:00
|
|
|
if (message.notification != null) {
|
|
|
|
_logger.info(
|
2022-06-11 08:23:52 +00:00
|
|
|
"Message also contained a notification: ${message.notification}",
|
|
|
|
);
|
2021-10-13 05:24:49 +00:00
|
|
|
}
|
2021-11-15 14:21:43 +00:00
|
|
|
if (shouldSync(message)) {
|
|
|
|
SyncService.instance.sync();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool shouldSync(RemoteMessage message) {
|
|
|
|
return message.data.containsKey(kPushAction) &&
|
2021-11-25 10:34:30 +00:00
|
|
|
message.data[kPushAction] == kSync;
|
2021-10-12 09:36:22 +00:00
|
|
|
}
|
2021-10-12 09:12:28 +00:00
|
|
|
}
|