Xamarin Forms基于AWS SNS实现推送:设备令牌获取与存储咨询
问题解决方案
一、设备令牌存入数据库的合理性
完全合理。AWS SNS推送必须依赖设备令牌定位目标设备,将令牌和用户账号绑定存储到数据库,是实现“定向推送给特定用户”的核心前提。需要注意两点:
- 令牌可能随用户卸载重装App、系统更新、设备重置发生变化,所以要在App每次启动时重新获取令牌并同步更新数据库记录,避免推送失败。
- 存储时必须关联用户ID,确保高优先级用户触发预订操作时,能精准查询到占用场地的低优先级用户对应的设备令牌。
二、iOS和Android端实现INotificationService接口
iOS端实现
[assembly: Dependency(typeof(NotificationService_iOS))] namespace YourAppName.iOS { public class NotificationService_iOS : INotificationService { public async Task<string> GetDeviceToken() { var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound; var notificationSettings = await UNUserNotificationCenter.Current.RequestAuthorizationAsync(authOptions); if (notificationSettings.AuthorizationStatus == UNAuthorizationStatus.Authorized) { UIApplication.SharedApplication.RegisterForRemoteNotifications(); var tcs = new TaskCompletionSource<string>(); NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidRegisterForRemoteNotificationsWithDeviceTokenNotification, (notification) => { var deviceToken = notification.Object as NSData; var tokenString = deviceToken.Description.Trim('<', '>').Replace(" ", ""); tcs.SetResult(tokenString); }); NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidFailToRegisterForRemoteNotificationsWithErrorNotification, (notification) => { var error = notification.Object as NSError; tcs.SetException(new Exception(error.LocalizedDescription)); }); return await tcs.Task; } else { throw new Exception("用户未授权通知权限"); } } } }
iOS端注意事项:
- 需在Info.plist中开启Push Notifications权限,并配置APNs环境(开发/生产)。
- iOS 10及以上版本必须使用
UNUserNotificationCenter处理权限请求。
Android端实现
[assembly: Dependency(typeof(NotificationService_Android))] namespace YourAppName.Droid { public class NotificationService_Android : INotificationService { public async Task<string> GetDeviceToken() { var context = Android.App.Application.Context; string token = null; int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(context); if (resultCode != ConnectionResult.Success) { throw new Exception("Google Play服务不可用,无法获取推送令牌"); } try { var instanceId = FirebaseInstanceId.Instance; token = await instanceId.GetTokenAsync("你的FCM发送者ID", FirebaseMessaging.InstanceIdScope); } catch (Exception ex) { throw new Exception("获取FCM令牌失败:" + ex.Message); } if (string.IsNullOrEmpty(token)) { throw new Exception("未能获取到设备令牌"); } return token; } } }
Android端注意事项:
- 需集成Firebase Cloud Messaging(FCM):添加
google-services.json文件,配置Gradle依赖。 - AndroidManifest.xml需添加相关权限和服务声明:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <service android:name=".MyFirebaseMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
三、后续流程建议
- App首次启动或每次启动时,调用
GetDeviceToken()获取令牌,将令牌与当前登录用户ID关联后更新到数据库。 - 高优先级用户触发预订操作时,后端查询数据库中占用场地的低优先级用户对应的设备令牌,调用AWS SNS接口发送推送通知。
内容的提问来源于stack exchange,提问作者Amature123
相关产品推荐
相关产品推荐

