iOS Firebase推送通知:如何给Firebase用户';s设备令牌并发送通知
最近在谷歌I/O活动上,谷歌对Firebase进行了翻新,添加了许多新功能,并对其余的功能进行了改进。我一直在尝试通过Firebase将iOS推送通知通过最基本的级别实现到我的应用程序中,因此我创建了一个非常简单的应用程序,除了接收远程推送通知之外,它实际上什么都不做 在Firebase内部,我上传了我的证书,在Xcode中,我的配置文件已添加到目标和项目中,在Firebase中,我上传了正确的证书。下面是我的iOS Firebase推送通知:如何给Firebase用户';s设备令牌并发送通知,ios,push-notification,firebase,Ios,Push Notification,Firebase,最近在谷歌I/O活动上,谷歌对Firebase进行了翻新,添加了许多新功能,并对其余的功能进行了改进。我一直在尝试通过Firebase将iOS推送通知通过最基本的级别实现到我的应用程序中,因此我创建了一个非常简单的应用程序,除了接收远程推送通知之外,它实际上什么都不做 在Firebase内部,我上传了我的证书,在Xcode中,我的配置文件已添加到目标和项目中,在Firebase中,我上传了正确的证书。下面是我的AppDelegate.swift文件中包含的代码,但因为我的ViewControll
AppDelegate.swift
文件中包含的代码,但因为我的ViewController.swift
是“空的”,所以我没有包含它
虽然没有崩溃或运行时错误,但当我加载应用程序时,我接受通知。然后,我退出应用程序并关闭设备。在Firebase中,我将通知发送到正确的应用程序。几分钟后,在Firebase,它说通知已经“完成”
但是,我从未在设备上收到通知。总之,我需要一个解决方案来发送Firebase thisdeviceToken
,然后使用“Firebase通知”发送推送通知消息
任何对我的代码或一般的帮助都将不胜感激,我希望这对未来的观众有所帮助。非常感谢。AppDelegate.swift中的我的代码:
import UIKit
import Firebase
import FirebaseMessaging
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FIRApp.configure()
let notificationTypes : UIUserNotificationType = [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound]
let notificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
application.registerForRemoteNotifications()
application.registerUserNotificationSettings(notificationSettings)
return true
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
print("Device Token: \(deviceToken)")
}
func applicationWillResignActive(application: UIApplication) {
}
func applicationDidEnterBackground(application: UIApplication) {
}
func applicationWillEnterForeground(application: UIApplication) {
}
func applicationDidBecomeActive(application: UIApplication) {
}
func applicationWillTerminate(application: UIApplication) {
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
print("MessageID : \(userInfo["gcm.messgae_id"]!)") // or gcm_etc...
print(userInfo)
}
}
现在,对于iOS的FCM来说,文档非常差
关注他们在github上的应用程序
此处添加了重要部分:
import Firebase
import FirebaseInstanceID
import FirebaseMessaging
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Register for remote notifications
if #available(iOS 8.0, *) {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else {
// Fallback
let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound]
application.registerForRemoteNotificationTypes(types)
}
FIRApp.configure()
// Add observer for InstanceID token refresh callback.
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.tokenRefreshNotificaiton),
name: kFIRInstanceIDTokenRefreshNotification, object: nil)
return true
}
func tokenRefreshNotificaiton(notification: NSNotification) {
let refreshedToken = FIRInstanceID.instanceID().token()!
print("InstanceID token: \(refreshedToken)")
// Connect to FCM since connection may have failed when attempted before having a token.
connectToFcm()
}
// [END refresh_token]
// [START connect_to_fcm]
func connectToFcm() {
FIRMessaging.messaging().connectWithCompletion { (error) in
if (error != nil) {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
}
}
}
现在,您的令牌已发送到FCM服务器Integrate而不使用CoCoapod
首先读取Firebase文档。=>
在Firebase上注册项目=>
从这里获取GoogleService-Info.plist文件=>project=>settings=>General
GoogleService-Info.plist文件放入项目中
设置通知。Firebase中的p12证书(生产和开发)
=>项目=>设置=>云消息传递
在此处下载Firebase SDK=>
在项目中创建SDK文件夹并删除其中的所有SDK文件夹
现在在Xcode=>libicucore.tbd中添加这个框架
在Xcode=>Projects=>Capabilities=>backgroundmodeon=>RemoteNotification中打开后台模式
添加您的Info.Plist文件FirebaseAppDelegateProxyEnabled设置BOOLNO
在Objective-c中
您的Appdelegate.m文件
#import "AppDelegate.h"
#import "Firebase.h"
#import "AFNHelper.h"
@interface AppDelegate (){
NSString *InstanceID;
}
@property (nonatomic, strong) NSString *strUUID;
@property (nonatomic, strong) NSString *strDeviceToken;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationType allNotificationTypes =
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
[FIRApp configure];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tokenRefreshNotification:) name:kFIRInstanceIDTokenRefreshNotification object:nil];
return YES;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(@"Message ID: %@", userInfo[@"gcm.message_id"]);
[[FIRMessaging messaging] appDidReceiveMessage:userInfo];
NSLog(@"userInfo=>%@", userInfo);
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[[FIRInstanceID instanceID] setAPNSToken:deviceToken type:FIRInstanceIDAPNSTokenTypeProd];
NSLog(@"deviceToken1 = %@",deviceToken);
}
- (void)tokenRefreshNotification:(NSNotification *)notification {
NSLog(@"instanceId_notification=>%@",[notification object]);
InstanceID = [NSString stringWithFormat:@"%@",[notification object]];
[self connectToFcm];
}
- (void)connectToFcm {
[[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error) {
if (error != nil) {
NSLog(@"Unable to connect to FCM. %@", error);
} else {
NSLog(@"InstanceID_connectToFcm = %@", InstanceID);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[self sendDeviceInfo];
NSLog(@"instanceId_tokenRefreshNotification22=>%@",[[FIRInstanceID instanceID] token]);
});
});
}
}];
}
更新:从Firebase 4.0.4开始,您可以
如何处理APNS设备令牌
我一直在阅读,但没有提到APNS设备令牌,它对推送通知至关重要
所以Firebase一定在引擎盖下做了些旋转动作。事实上是这样。通过阅读后端文档,我们可以了解这一点
Swizzling已禁用:映射您的APNs令牌和注册令牌
If you have disabled method swizzling, you'll need to explicitly map your APNs token to the FCM registration token. Override the
方法didRegisterForRemotonificationsWithDeviceToken
检索
输入APNs令牌,然后调用setAPNSToken
我特别尽量避免喝太多的酒。阅读给了我们如何去做
启用/禁用方法swizzling
FCM提供的方法swizzling简化了客户端代码。
但是,对于不喜欢使用它的开发人员,FCM允许您
通过添加
应用程序的Info.plist文件中的firmMessageAutoRegisterEnabledFlag,以及
将其值设置为“否”(布尔值)
适用时,本指南提供了和的迁移示例
不启用方法swizzling
显示代码
在您的pod文件中保存此文件
pod 'Firebase'
pod 'FirebaseMessaging'
这是完整的代码
import Firebase
import FirebaseMessaging
override func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FIRApp.configure()
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(tokenRefreshNotification(_:)),
name: kFIRInstanceIDTokenRefreshNotification,
object: nil)
}
// NOTE: Need to use this when swizzling is disabled
public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Sandbox)
}
func tokenRefreshNotification(notification: NSNotification) {
// NOTE: It can be nil here
let refreshedToken = FIRInstanceID.instanceID().token()
print("InstanceID token: \(refreshedToken)")
connectToFcm()
}
func connectToFcm() {
FIRMessaging.messaging().connectWithCompletion { (error) in
if (error != nil) {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
}
}
}
public func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print(userInfo)
}
“关闭我的设备。”呃,如果设备已关闭,您如何接收通知?您的意思是在重新打开设备后未收到通知吗?这是预期的行为。因此,在我的iPhone上,我第一次打开应用程序。我接受启用通知弹出窗口。然后我退出应用程序并将其关闭。我所期待的是,当通知通过时,通知会出现在您的锁屏上,然后点亮锁屏,但什么也没有发生。如果您关闭设备,没有锁屏,如果它关闭,怎么会有锁屏?如果你把它关掉,就没有电了。所以我不明白你在说什么,当你一直说关掉它。到底关闭什么?不管怎样,除此之外,假设设备已打开,但您仍然没有得到推送。您的代码在任何地方都无法获取推送令牌。因此,您是如何向firebase提供推送令牌的?这就是我有点困惑的地方。我认为不需要设备令牌,firebase会将通知发送给拥有该应用程序的所有人。当我说“关”的时候,我不是指一路断电,而是指你可以向左滑动并输入密码的地方。谢谢。谢谢,但是我在调用选择器时遇到一个错误:#selector您需要使用xcode 7.3作为#选择器语法。否则,您可以尝试选择器:“self.tokenRefreshNotification:”
我已经实现了上述代码,还将p12设置为firebase->Settings->Cloud Messaging,是的,我可以在firebase->notification->New Message时获得推送通知…..但是self.ref.child(“messages”).childByAutoId().setValue(mdata)未收到推送通知…您应该将此作为单独的问题@Idevelopers提问,但您有什么想法吗?我这样做并检查了。我以为我收到过一次通知,但无法再次收到。检查我在这里发布的问题,我在其中输入了我的全部代码:当iOS应用程序处于后台或前台模式时,这可以正常工作。但当iOS应用程序终止时,它不起作用。我无法收到推送通知
pod 'Firebase'
pod 'FirebaseMessaging'
import Firebase
import FirebaseMessaging
override func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FIRApp.configure()
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(tokenRefreshNotification(_:)),
name: kFIRInstanceIDTokenRefreshNotification,
object: nil)
}
// NOTE: Need to use this when swizzling is disabled
public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Sandbox)
}
func tokenRefreshNotification(notification: NSNotification) {
// NOTE: It can be nil here
let refreshedToken = FIRInstanceID.instanceID().token()
print("InstanceID token: \(refreshedToken)")
connectToFcm()
}
func connectToFcm() {
FIRMessaging.messaging().connectWithCompletion { (error) in
if (error != nil) {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
}
}
}
public func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print(userInfo)
}