Firebase push notification

This commit is contained in:
2024-06-07 00:00:28 +08:00
parent 0b8daad945
commit 0d179f6544
6 changed files with 105 additions and 2 deletions

View File

@@ -173,11 +173,12 @@ class AccountProvider extends GetxController {
if (!await auth.isAuthorized) throw Exception('unauthorized');
final deviceUuid = await PlatformDeviceId.getDeviceId;
final token = await FirebaseMessaging.instance.setAutoInitEnabled(true);
final token = await FirebaseMessaging.instance.getToken();
// TODO On iOS/macOS, using getAPNSToken() instead.
final client = auth.configureClient(service: 'passport');
final resp = await client.post('/api/notifications/subtribe', {
final resp = await client.post('/api/notifications/subscribe', {
'provider': 'firebase',
'device_token': token,
'device_id': deviceUuid,

View File

@@ -6,6 +6,7 @@ import 'package:solian/router.dart';
import 'package:solian/screens/auth/signin.dart';
import 'package:solian/screens/auth/signup.dart';
import 'package:solian/widgets/account/account_heading.dart';
import 'package:solian/widgets/account/push_notify_register_dialog.dart';
class AccountScreen extends StatefulWidget {
const AccountScreen({super.key});
@@ -101,6 +102,31 @@ class _AccountScreenState extends State<AccountScreen> {
setState(() {});
},
),
const Divider(thickness: 0.3, height: 0.3)
.paddingSymmetric(vertical: 16),
Wrap(
spacing: 4,
children: [
InkWell(
child: Text(
'pushNotifyRegisterAction'.tr,
style: TextStyle(
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.85),
),
),
onTap: () {
showDialog(
context: context,
builder: (context) =>
const PushNotifyRegisterDialog(),
);
},
)
],
)
],
);
},

View File

@@ -3,6 +3,7 @@ import 'package:get/get.dart';
import 'package:solian/exts.dart';
import 'package:solian/providers/auth.dart';
import 'package:solian/services.dart';
import 'package:solian/widgets/account/push_notify_register_dialog.dart';
import 'package:url_launcher/url_launcher_string.dart';
class SignInPopup extends StatefulWidget {
@@ -23,6 +24,11 @@ class _SignInPopupState extends State<SignInPopup> {
final password = _passwordController.value.text;
if (username.isEmpty || password.isEmpty) return;
provider.signin(context, username, password).then((_) async {
await showDialog(
context: context,
builder: (context) => const PushNotifyRegisterDialog(),
);
Navigator.pop(context, true);
}).catchError((e) {
List<String> messages = e.toString().split('\n');

View File

@@ -193,6 +193,11 @@ class SolianMessages extends Translations {
'badgeSolsynthStaff': 'Solsynth Staff',
'badgeSolarOriginalCitizen': 'Solar Network Natives',
'badgeGreatCommunityContributor': 'Great Community Contributor',
'pushNotifyRegisterAction': 'Enable Push Notifications',
'pushNotifyRegister': 'Register Push Notification Device',
'pushNotifyRegisterCaption':
'Activating push notifications allows you to get our latest notifications even when the app is completely closed. We use Apple\'s official push service on iOS/macOS devices; other devices provide push notifications through Google Firebase. To register a device for push notifications, you may need to connect to Google\'s servers and install the Google Framework on your device.',
'pushNotifyRegisterDone': 'Push Notifications has been activated.',
},
'zh_CN': {
'hide': '隐藏',
@@ -372,6 +377,11 @@ class SolianMessages extends Translations {
'badgeSolsynthStaff': 'Solsynth 工作人员',
'badgeSolarOriginalCitizen': 'Solar Network 原住民',
'badgeGreatCommunityContributor': '优秀社区贡献者',
'pushNotifyRegisterAction': '激活推送通知',
'pushNotifyRegister': '注册推送通知设备',
'pushNotifyRegisterCaption':
'激活推送通知便可以让你在应用程序完全关闭的时候仍然获取到我们最新的通知。在 iOS/macOS 设备上我们使用 Apple 官方的推送服务;其他设备则通过 Google Firebase 提供推送通知。要注册推送通知设备,您可能需要连接到 Google 的服务器(在中国大陆不可用)并在您的设备上安装 Google Framework。',
'pushNotifyRegisterDone': '推送通知已成功激活',
}
};
}

View File

@@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:solian/exts.dart';
import 'package:solian/providers/account.dart';
class PushNotifyRegisterDialog extends StatefulWidget {
const PushNotifyRegisterDialog({super.key});
@override
State<PushNotifyRegisterDialog> createState() =>
_PushNotifyRegisterDialogState();
}
class _PushNotifyRegisterDialogState extends State<PushNotifyRegisterDialog> {
bool _isBusy = false;
void performAction() async {
setState(() => _isBusy = true);
try {
await Get.find<AccountProvider>().registerPushNotifications();
context.showSnackbar('pushNotifyRegisterDone'.tr);
Navigator.pop(context);
} catch (e) {
context.showErrorDialog(e);
}
setState(() => _isBusy = false);
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('pushNotifyRegister'.tr),
content: Text('pushNotifyRegisterCaption'.tr),
actions: [
TextButton(
onPressed: _isBusy ? null : () => Navigator.pop(context),
child: Text('cancel'.tr),
),
TextButton(
onPressed: _isBusy ? null : performAction,
child: Text('confirm'.tr),
),
],
);
}
}