【发布时间】:2019-06-25 04:37:17
【问题描述】:
我做了以下事情:
- 在 FCM 控制台中创建了一个项目并将 ios 项目添加到其中。
- 下载
GoogleService-Info.plist并将其添加到xamarin forms ios项目目录并将构建操作设置为Bundlesource。 - 在 Info.plist 上启用远程通知后台模式。
- 在应用的 Info.plist 文件中添加了 FirebaseAppDelegateProxyEnabled 并将其设置为否。
- 创建了配置文件和分发证书并将其安装到钥匙串访问中。此外,将这些证书映射到项目选项中。
- 在 FCM 控制台中上传了 .p12 证书。
- 在
AppDelegate.cs中添加了处理推送通知的代码。
我的代码:
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate, IUNUserNotificationCenterDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App("",""));
RequestPushPermissionsAsync();
_launchoptions = options;
// Register your app for remote notifications.
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
// iOS 10 or later
var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) => {
Console.WriteLine(granted);
});
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.Current.Delegate = this;
// For iOS 10 data message (sent via FCM)
//Messaging.SharedInstance.RemoteMessageDelegate = this;
}
else
{
// iOS 9 or before
var allNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
var settings = UIUserNotificationSettings.GetSettingsForTypes(allNotificationTypes, null);
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
UIApplication.SharedApplication.RegisterForRemoteNotifications();
return base.FinishedLaunching(app, options);
}
NSDictionary _launchoptions;
public override void OnActivated(UIApplication uiApplication)
{
base.OnActivated(uiApplication);
if (_launchoptions != null && _launchoptions.ContainsKey(UIApplication.LaunchOptionsRemoteNotificationKey))
{
var notfication = _launchoptions[UIApplication.LaunchOptionsRemoteNotificationKey] as NSDictionary;
PresentNotification(notfication);
}
_launchoptions = null;
}
async Task RequestPushPermissionsAsync()
{
var requestResult = await UNUserNotificationCenter.Current.RequestAuthorizationAsync(
UNAuthorizationOptions.Alert
| UNAuthorizationOptions.Badge
| UNAuthorizationOptions.Sound);
bool approved = requestResult.Item1;
NSError error = requestResult.Item2;
if (error == null)
{
if (!approved)
{
Console.Write("Permission to receive notification was not granted");
return;
}
var currentSettings = await UNUserNotificationCenter.Current.GetNotificationSettingsAsync();
if (currentSettings.AuthorizationStatus != UNAuthorizationStatus.Authorized)
{
Console.WriteLine("Permissions were requested in the past but have been revoked (-Settings app)");
return;
}
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
else
{
Console.Write($"Error requesting permissions: {error}.");
}
}
public async override void RegisteredForRemoteNotifications(
UIApplication application, NSData deviceToken)
{
//if (deviceToken == null)
//{
// // Can happen in rare conditions e.g. after restoring a device.
// return;
//}
//Console.WriteLine($"Token received: {deviceToken}");
// Get current device token
var DeviceToken = deviceToken.Description;
if (!string.IsNullOrWhiteSpace(DeviceToken))
{
DeviceToken = DeviceToken.Trim('<').Trim('>');
}
Console.WriteLine($"deviceToken received: {deviceToken}");
Console.WriteLine($"DeviceToken received: {DeviceToken}");
// Get previous device token
var oldDeviceToken = NSUserDefaults.StandardUserDefaults.StringForKey("PushDeviceToken");
// Has the token changed?
if (string.IsNullOrEmpty(oldDeviceToken) || !oldDeviceToken.Equals(DeviceToken))
{
//TODO: Put your own logic here to notify your server that the device token has changed/been created!
}
// Save new device token
NSUserDefaults.StandardUserDefaults.SetString(DeviceToken, "PushDeviceToken");
await SendRegistrationToServerAsync(DeviceToken);
}
async Task SendRegistrationTokenToMainPRoject(NSData deviceToken)
{
MessagingCenter.Send<object, string>(this, "fcmtoken", deviceToken.ToString());
}
public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
{
Console.WriteLine($"Failed to register for remote notifications: {error.Description}");
}
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo,
Action<UIBackgroundFetchResult> completionHandler)
{
PresentNotification(userInfo);
completionHandler(UIBackgroundFetchResult.NoData);
try
{
UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary;
var message = (aps[new NSString("webContentList")] as NSString).ToString();
LoadApplication(new App("", message));
}
catch (Exception ex)
{
//LogInfo.ReportErrorInfo(ex.Message, ex.StackTrace, "AppDelegate-DidReceiveRemoteNotification");
}
}
void PresentNotification(NSDictionary userInfo)
{
NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary;
var msg = string.Empty;
if (aps.ContainsKey(new NSString("alert")))
{
msg = (aps[new NSString("alert")] as NSString).ToString();
}
if (string.IsNullOrEmpty(msg))
{
msg = "(unable to parse)";
}
MessagingCenter.Send<object, string>(this, App.NotificationReceivedKey, msg);
}
}
我没有在 ios 部分使用任何 NuGet 包。将项目运行到设备中时,FCM 令牌生成部分正在工作,我可以在 VS 控制台上看到 fcm 令牌。我试图从邮递员向设备发送测试通知,但收到InvalidRegistration 错误。
邮递员回复
{
"multicast_id": 8754155136812875313,
"success": 0,
"failure": 1,
"canonical_ids": 0,
"results": [
{
"error": "InvalidRegistration"
}
]
}
邮递员身体
{
"to" : "d20ad003 7473bfba 85dffc33 1534decf b4b886f1 c738878f fd7f2c60 d9dabc36",
"collapse_key" : "type_a",
"data" : {
"body" : "Body of Your Notification in Data",
"title": "Title of Your Notification in Title",
"key_1" : "Value for key_1",
"key_2" : "Value for key_2"
},
"notification" : {
"body" : "Body of Your Notification",
"title": "Title of Your Notification",
"sound": "default",
"content_available" : true
}
}
我已经完成了 android 部分的实现,并且在从邮递员推送时收到通知。但是在 ios 部分出现 InvalidRegistration 错误并且在我的 ios 设备中没有收到任何通知。
我关注this youtube 视频进行此实现,完整源代码为here。
任何人都建议解决此问题。
提前致谢。
更新
我创建了一个示例项目和一个邮递员集合并将其添加到我的google folder。
Postman 集合包含 2 个 REST API,一个用于 Android 设备,另一个用于 ios 设备
如果您导入邮递员集合并运行 Android REST API,我将收到通知,因为我已在其上添加了我的设备 FCM 令牌。但是在 postman 中运行 ios REST API 时会在 postman 中返回 InvalidRegistration 错误。
请通过示例项目,请给我一个解决方案?
【问题讨论】:
-
我之前没用过FCM,但不知道你是否需要在AppDelegate.cs中为firebase做任何初始化?像这样的东西:FCM.iOS
-
@JackHua-MSFT 我没有在 ios 部分使用任何 nuget 包,并且在视频中他没有讲述 firebase 的初始化。github.com/Krumelur/XamUAzureNotificationHub/blob/master/…
-
@JackHua-MSFT 我已经用一个示例项目更新了这个问题,你能看看吗?
-
好的,我去看看。
标签: xamarin.forms xamarin.ios firebase-cloud-messaging