ninguna - Notificaciones push de Firebase para iOS: cómo proporcionar tokens de dispositivo del usuario de Firebase y enviar notificaciones
id de clave firebase (3)
Recientemente, en el evento de E / S de Google, Google renovó Firebase y agregó muchas características nuevas, y retocó las restantes. He estado tratando de implementar las notificaciones push de iOS a través de Firebase en mi aplicación a través del nivel más básico, así que creé una aplicación muy simple que realmente no hace nada más que recibir notificaciones push remotas.
Dentro de Firebase, he subido mi certificado y dentro de Xcode mis perfiles de aprovisionamiento se han agregado tanto al objetivo como al proyecto, y en Firebase he subido el certificado correcto.
A continuación se muestra el código contenido dentro de mi archivo
AppDelegate.swift
pero porque mi
ViewController.swift
está "vacío", no lo incluí.
Aunque no hay fallas ni errores de tiempo de ejecución, cuando cargo la aplicación, acepto las notificaciones. Luego, salgo de la aplicación y apago mi dispositivo. En Firebase, envío la notificación a la aplicación correcta. Después de un par de minutos, en Firebase dice que la notificación fue "Completada".
Sin embargo, nunca recibí la notificación en el dispositivo.
En conclusión, necesito una solución para enviar Firebase a este
deviceToken
y luego usar ''Notificaciones de Firebase'' para enviar el mensaje de notificación push.
Cualquier ayuda para mi código o en general sería muy apreciada y espero que esto ayude a los futuros espectadores.
¡Gracias!
Mi código en
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)
}
}
Integrar sin CocoaPods
Primero lea Firebase Doc. => Firebase Doc
Registre el proyecto en Firebase aquí => Registre el proyecto aquí
Obtenga el archivo GoogleService-Info.plist desde aquí => project => settings => General
El archivo GoogleService-Info.plist cae en su proyecto.
establecer Certificados de Notificación .p12 (Producción y Desarrollo) en Firebase => proyecto => configuración => Mensajería en la Nube
Descarga Firebase SDK aquí => Firebase SDK Descargar
Cree la carpeta SDK en su proyecto y suelte toda la carpeta SDK en ella.
Ahora agregue este marco en su Xcode => libicucore.tbd
- Active los modos de fondo en Xcode => Proyectos => Capacidades => Modo de fondo activado => Notificación remota
- Agregue su archivo Info.Plist FirebaseAppDelegateProxyEnabled Set BOOL NO .
En Objective-c su archivo 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]);
});
});
}
}];
}
Actualizado: a partir de Firebase 4.0.4, puede seguir https://github.com/onmyway133/blog/issues/64
CÓMO SE MANEJA EL DISPOSITIVO APNS TOKEN
He estado leyendo Enviar una notificación a un segmento de usuario en iOS, pero no se menciona el token del dispositivo APNS, que es crucial para las notificaciones automáticas.
Por lo tanto, Firebase debe estar haciendo algunos movimientos debajo del capó. De hecho lo es. La lectura de la documentación del backend Downstream Messages nos da la idea
Swizzling deshabilitado: mapeo de su token APN y token de registro
If you have disabled method swizzling, you''ll need to explicitly map your APNs token to the FCM registration token. Override the
Los métodos
didRegisterForRemoteNotificationsWithDeviceToken
para recuperar el token APN y luego llamar asetAPNSToken
.
func application(application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenTypeSandbox)
}
Particularmente trato de evitar el swizzling tanto como sea posible. Leer Migrar una aplicación de cliente GCM para iOS a Firebase Cloud Messaging nos da cómo deshabilitarla
Habilitar / deshabilitar el método swizzling
El método swizzling disponible con FCM simplifica su código de cliente. Sin embargo, para los desarrolladores que prefieren no usarlo, FCM le permite deshabilitar la combinación de métodos al agregar FIRMessagingAutoRegisterEnabledflag en el archivo Info.plist de la aplicación y establecer su valor en NO (valor booleano).
FCM swizzling affects how you handle the default registration token, and how you handle downstream message callbacks. Where
aplicable, esta guía proporciona ejemplos de migración con y sin método swizzling habilitado.
Muéstrame el código
Ten esto en tu
Podfile
pod ''Firebase''
pod ''FirebaseMessaging''
Aquí está el código completo
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)
}
Los documentos son bastante pobres para el FCM para iOS ahora.
Sigue la aplicación de sample que tienen en github
Parte importante agregada aquí:
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.")
}
}
}
Ahora su token ha sido enviado al servidor FCM