Failing to implement Firebase Phone Auth on iOS - ios

hey so I have a function Firebase/iOS app and am trying to implement phone auth.
pods are installed
APNs authentication key uploaded to Firebase
Push notifs enabled in Xcode
calling this method
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) { (verificationID, error) in
if let error = error {
self.showMessagePrompt(error.localizedDescription)
return
}
// Sign in using the verificationID and the code sent to the user
// ...
}
in the view controller and passing a valid number.
I get this error ->
The UIApplicationDelegate must handle remote notification for phone number authentication to work.
Error Domain=FIRAuthErrorDomain Code=17054 "If app delegate swizzling is disabled, remote notifications received by UIApplicationDelegate need to be forwarded to FIRAuth's canHandleNotificaton: method." UserInfo={NSLocalizedDescription=If app delegate swizzling is disabled, remote notifications received by UIApplicationDelegate need to be forwarded to FIRAuth's canHandleNotificaton: method., error_name=ERROR_NOTIFICATION_NOT_FORWARDED}
Swizzling is not disabled not that I know of. Delegate doesn't have much goin on but this walkthrough https://firebase.google.com/docs/auth/ios/phone-auth didn't mention it.
I'm not getting the silent notification I assume and def not receiving an SMS.
Thanks.

Please add following code in your AppDelegate:
func application(_ application: UIApplication,
didReceiveRemoteNotification notification: [AnyHashable : Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
if Auth.auth().canHandleNotification(notification) {
completionHandler(.noData)
return
}
// This notification is not auth related, developer should handle it.
handleNotification(notification)
}

Related

iOS Swift Twilio Programmable Chat Push Notifications

Using the TwilioChatClient pod, I have successfully registered my app to Twilio Programmable Chat to receive APN notifications.
However, from what I can tell, these notifications are being created after calling client.register(withToken: deviceToken) on an instantiated TwilioChatClient client, and NOT through the application's AppDelegate didReceiveRemoteNotification method. Stranger yet, didReceiveRemoteNotification is called, but only when the application is in the active state, and not the background state, where I would like to perform some operations.
Does anyone know where and how these notifications are being created, or why didReceiveRemoteNotification is only called during the active state? Amongst other things, I would like to increment the application icon badge number with each notification sent out by the client.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("Registered for notifications");
if UserUtils.client?.userInfo != nil {
print("Has info");
UserUtils.deviceToken = deviceToken;
UserUtils.client?.register(withToken: deviceToken)
} else {
print("No info");
updatedPushToken = deviceToken as NSData?
}
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
print("Received a notification");
if UIApplication.shared.applicationState != .active {
print(userInfo);
UserUtils.client?.handleNotification(userInfo);
UIApplication.shared.applicationIconBadgeNumber += 1;
if UserUtils.client?.userInfo != nil {
print(userInfo);
let jsonNotification = JSON(userInfo["aps"])
let alert = jsonNotification["alert"].stringValue + "\"}";
print(JSON.init(parseJSON: alert)["body"]);
} else {
print(userInfo);
let jsonNotification = JSON(userInfo["aps"])
let alert = jsonNotification["alert"].stringValue + "\"}";
print(JSON.init(parseJSON: alert)["body"]);
}
} else {
}
}
where the client.register(withToken: deviceToken) works as intended.
Twilio developer evangelist here.
I've spoken with the Programmable Chat team and this is what I've found out:
application(_:didReceiveRemoteNotification:fetchCompletionHandler:) is for silent notifications in the background that perform background processing only (that is, with "content-available": 1 set in the APNS notification). Programmable Chat sends notifications that show information to the user, so it won't be fired in background mode
Notifications can update the badge count for you though, so this is processing you don't have to do, this requires a different setting in the notification that we currently do not support, however work is being done to add that support now
If you want to both show a notification and do further background processing, this is not supported in regular notifications, however this is supported with iOS 10's service extensions. Programmable Chat doesn't support those either, but again, it is being worked on, so you may see that soon
Keep an eye on the Programmable Chat Changelog for these additions.
Let me know if that helps at all.

Firebase messaging iOS : usersInfo is empty or I never get the notification

I follow the rules from the Google Firebase for configuring my iOS app. When I give to the Firebase Console a Device ID (token) which has never been used, the notification is caught by my app, but the userInfo is empty:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// Print message ID.
print("Message ID: \(userInfo["gcm.message_id"]!)") /* HERE */
// Print full message.
print("%#", userInfo)
}
On the line with the /* HERE */ comment, the app crashes because userInfo is nil.
When I try again another notification from the Firebase console, the notification is not caught and nothing appends (I have a breakpoint in the reception notification function).
What's wrong ?
Make sure you are using the Firebase token that is generated and not the device token that made this mistake. You will need to put this in your code to get the token you need:
print(FIRInstanceID.instanceID().token())
I put this inside of my code:
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {}

How to get notification additionaldata(payloadData) that was at AppDelegate' didFinishLunchingWithOptions if the user didn't open the notification

I am currently using OneSignal for notification service to my app.I really need a help with accessing notification additionaldata(payload data) from AppDelegate inside didFinishLunchingWithOption where OneSignal API can give me like this.
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var data : [NSObject : AnyObject]!
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let oneSignal = OneSignal(launchOptions: launchOptions, appId: "48755d3d-abc0-4bac-8f71-095729bb3a65") { (message, additionalData, isActive) in
NSLog("OneSignal Notification opened:\nMessage: %#", message)
if additionalData != nil {
NSLog("additionalData: %#", additionalData)
self.data = additionalData
print(self.data)
}
}
oneSignal.enableInAppAlertNotification(true)
return true
}
}
but,I can only get the data if user click notification when appear or open it from notification center.So,if user neglect that notification without tapping when appear or without swiping or tapping from notification center,how do i get the additional data?
Actually,I want to store all payload data every time it comes into my device at realm database and fetch the data from my server according to that payload data.
You should use application(_:didReceiveRemoteNotification:fetchCompletionHandler:).
If you have enabled remote notifications background mode most of your notifications will be delivered even if the app is not running in the foreground. The only caveat being that the app must have been launched (since notifications are being pushed the user has done this) and it mustn't have been force-quit by the user.
More info in Apple's docs about that specific method.
Or in the "Local and Remote Notification Programming Guide's" notification handling chapter
You can extract all the payload in did finishLaunching by following method..
Let data = launchOptions.objectForKey(UIApplicationLaunchOptionsUIApplicationLaunchOptionsRemoteNotificationUIApplicationLaunchOptionsUIApplicationLaunchOptionsRemoteNotificationKey)

Handling push notifications payload data

I am searching the way about how to handle push notification payload data as soon as the notification reaches to the client app without opening or tapping it.And I am still not getting the data unless the user tap or open it from notification center or banner or alert.The function didReceiveRemoteNotification only triggered when the user click the notification on the screen.So,how to get the notification payload data when the notification arrive to client app even the user ignore(without open or tap) it.
INFO : I heard that GCM(Google Cloud Messaging) can make notification handler if the client app user tapped the notification or not.It can catch the notification payload json data as soon as it reach the client app without even need user to tap or open it.Is that right?
I really need a hand to pick me up with getting notification payload data on ios without even need a user to open or tap it.
Update : The app is still running on device which mean it was active.I can get the payload data when i click my notification which was "{aps:} json i get it.But,I still cant get the data when i don't open the notification"
Here is my state
When the app was at foreground,I get the data.
1.I run the App,
2.Send Notification,
3.Get the notification with an alert,
4.I get the data(payload).
Work fine when app is active.
But,when the app reach to background
1.Run The app,
2.Close The App by pressing home button,
3.Send Notification,
4.Get the notification.
5.But,cant get the data until i click notification that I was receive at banner
or notification center.
But,when i click the notification at banner or notification it went to app and then i get the data.
Is there anyway that i can get the data if the app in background when the notification received.
Here is the code :
import UIKit
import RealmSwift
let realm = try! Realm()
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var data : [NSObject : AnyObject]!
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//one singnal is the push notification service that i use for push notification.
let oneSignal = OneSignal(launchOptions: launchOptions, appId: "__app_id__") { (message, additionalData, isActive) in
NSLog("OneSignal Notification opened:\nMessage: %#", message)
if additionalData != nil {
NSLog("additionalData: %#", additionalData)
}
}
oneSignal.enableInAppAlertNotification(true)
return true
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
print("User Info : \(userInfo)")
if let custom = userInfo["custom"] as? NSDictionary{
if let a = custom["a"] as? NSDictionary{
print("A : \(a)")
}
}
}
I came across the same problem. As mentioned in the previous comments, this post is quite helpful.
According to Apple,
When a remote notification arrives, the system displays the
notification to the user and launches the app in the background (if
needed) so that it can call this method. Launching your app in the
background gives you time to process the notification and download any
data associated with it, minimizing the amount of time that elapses
between the arrival of the notification and displaying that data to
the user.
The first thing you have to do is to allow your app to do something when in background. You do this by adding Required background mode in your info.plist, then add it App downloads content in response to push notifications. Your info.plist should look something like this:
Now this is done, your app should awake when it receive a notification. You can execute a small code inside didReceiveRemoteNotification. Such as this.
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
//do some code here
UIBackgroundFetchResult.NewData
}
Note that you have to pay attention to the completionHandler:
As soon as you finish processing the notification, you must call the
block in the handler parameter or your app will be terminated. Your
app has up to 30 seconds of wall-clock time to process the
notification and call the specified completion handler block.
Let me know if everything is clear :)

Swift: didReceiveRemoteNotification to be called with no user activity involved (Using Houston ruby gem)

I have a small swift app written. I have successfully configured the remote notification services. Here is the code
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
println("received notification")
var remoteServer = RemoteServer()
remoteServer.sendDataToServer { (success) -> () in
completionHandler(UIBackgroundFetchResult.NewData)
}
}
Now, I am using Houston ruby gem to send the notifications. which looks something like this
require 'houston'
APN = Houston::Client.production
APN.certificate = File.read("production_certificate.pem")
token = "token here"
notification = Houston::Notification.new(device: token)
notification.content_available = true
notification.alert = "test"
notification.badge = 0
APN.push(notification)
I can successfully see the message on the lock screen. But its when I swipe the notification , which opens the app, thats when the didReceiveRemoteNotification method gets called.
I am wondering if there is a way to fire off didReceiveRemoteNotification without the user having to swipe the notification ? (Pretty much no user activity required) ?
I tried setting the alert to nil. But then since no user activity can be detected didReceiveRemoteNotification never gets fired off.
How should I handle this scenario? Should I be using performFetchWithCompletionHandler , but then how to fire it from the remote server?
UPDATE: the didReceiveRemoteNotification does get sent out when the app is currently opened, but as soon as the device is locked. The same isn't getting called.
Thanks

Resources