Facebook iOS Swift SDK: Not getting callback - ios

I'm using the facebook getting started guide to create a simple facebook login. (https://developers.facebook.com/docs/swift/login)
Whenever I tap the button it opens the facebook login view, lets me log in but afterwards doesn't fire a callback. The view just stays open and white.
let loginButton = LoginButton(readPermissions: [ .publicProfile ])
loginButton.center = view.center
view.addSubview(loginButton)
All I'm getting in the console is the following, if that's of any help:
2016-09-27 01:14:41.294 app[48118:6370539] -canOpenURL: failed for URL: "fbauth2:/" - error: "The operation couldn’t be completed. (OSStatus error -10814.)"

Turns out I was missing the AppDelegate part to handle url opens:
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return SDKApplicationDelegate.shared.application(application,
open: url,
sourceApplication: sourceApplication,
annotation: annotation)
}

You have to allow Key-Chain sharing for iOS10: https://stackoverflow.com/a/39568942/3463712
and you have to add below code in your info.plist file
<key>NSAppTransportSecurity</key>
<dict>
<!--Include to allow all connections (DANGER)-->
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
and also
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>
<!--You need only fbauth2, other parameters are reference for more functionality of Facebook-->
Do this and let me know if your problem solves. Thanks.
EDIT:
May be problem is in your loginbutton.
below code is working fine for me.
let loginbtn = FBSDKLoginButton()
loginbtn.center = view.center
loginbtn.readPermissions = ["public_profile"];
self.view.addSubview(loginbtn)

Related

Facebook iOS SDK login error (Invalid Scopes: public_profile, openid.)

I receive the follow error when trying to login using the iOS Facebook SDK:
Invalid Scopes: public_profile, openid.
I have followed the instructions from here which has resulted in this set up:
info.plist
<plist version="1.0">
<dict>
...
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string></string>
<key>CFBundleURLSchemes</key>
<array>
<string>GOOGLE_URL_SCHEME</string>
<string>fbMY_FB_APP_ID</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>MY_FB_APP_ID</string>
<key>FacebookClientToken</key>
<string>MY_FB_CLIENT_TOEN</string>
<key>FacebookDisplayName</key>
<string>MY_FB_APP_NAME</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbauth2</string>
<string>fbapi</string>
<string>fb-messenger-share-api</string>
</array>
</dict>
</plist>
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
ApplicationDelegate.shared.application( application, didFinishLaunchingWithOptions: launchOptions )
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]
) -> Bool {
return ApplicationDelegate.shared.application(app, open: url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplication.OpenURLOptionsKey.annotation])
}
Login snippet
let loginManager = LoginManager()
loginManager.logIn(permissions: ["public_profile"], from: self) { result, error in
if let error = error {
print("FB Error: \(error)")
} else if let result = result, result.isCancelled {
print("FB Cancelled")
} else {
print("FB Logged In")
}
}
I am on iOS 16.2 using the facebook-ios-sdk version 15.1.0. The same error occurs with FB app in live and development mode. I receive the same error on the simulator and device. I can successfully login on the web when using the FB app JS library. I believe I have followed the instructions correctly. What am I missing?
Edit: Settings Screenshots
Edit:
So I just downloaded this sample from the facebook-ios-sdk. Added my FB App Id to the FacebookAppID field and URL Schemes in the plist. Added the FB Client Token to the plist and updated the bundle identifier to the one listed in the Facebook app, but I get the same error when I run the sample. What the hell is going on? The issue must be in the Facebook app set up, but where? I can't find this issue reported anywhere on the net. Surely someone has seen this before.
I figured it out. I was missing the facebook login from my facebook app products. I found it by accident and now I can login successfully.

SWIFT - FBSDKLoginManager error when using FB App

I'm using the FBSDKLoginManager to receive a token for later usage (FB posting) and end up in an endless loop after confirming the access.
When calling the FBSDKLoginManager(), the following popup appears (Sorry, it's in German language... This is the official Facebook popup, where the user can select whether he wants to logon manually or using the FB App).
Now the following error occurs:
If I'm using the second button (logon via phone number or E-Mail-Address), everything works fine. The function returns with a token and I can go on in my App.
The ERROR: If I'm using the first button (logon with Facebook-App), the Facebook App opens, I can set all the privacy settings in FB, and confirm. After confirming the access, the FB-App closes automatically and returns to the same popup-screen without any change. No action occurs after coming back to this screen...
I don't have any foggy idea where the problem is... There is no error message. Due to the fact that everything works fine when using the E-Mail Login, the problem must be in the return of the FB-App. The E-Mail Login works via Safari, in the error case there is the break to the FB-App.
let login: FBSDKLoginManager = FBSDKLoginManager()
login.logIn(withPublishPermissions: ["publish_actions"], from: self) { (result, error) in
if (error != nil) {
print("publish_actions: \(error!)")
} else if (result?.isCancelled)! {
print("publish_actions: Canceled")
} else if (result?.grantedPermissions.contains("publish_actions"))! {
//print("publish_actions: permissions granted: \(String(describing: result?.token.tokenString))")
UserDefaults.standard.set(result?.token.tokenString, forKey: "facebook_token")
}
Added Frameworks: Bolts / CoreKit / LoginKit
Development Environment: Xcode 9.2 / iPhone 6s with iOS 11.2 / latest Facebook App installed.
I solved by adding the follow missing call to FB SDK:
[[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
inside
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation method of the AppDelegate.
Check for following
in your info plist file
<key>FacebookAppID</key>
<string>fb_id_here</string> // in format 234234234
<key>FacebookDisplayName</key>
<string>display_name_here</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>fbfb_id_here </string>. // in format fb234234234
</array>
</dict>
</array>
now inyour appdelegate
in
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
SDKApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
if let scheme = url.scheme {
if scheme == "fb 234234234" { //the one you kept in your info plist file
//TODO: replace with real value
return SDKApplicationDelegate.shared.application(application, open: url, options: options)
}
}
return true
}
Do configure these and then dub your app, if the control folw comes in appdelegate function
func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool
if it doesnt you have not configured facebook schemas correctly in info plist file
also
let fbManager = FBSDKLoginManager()
fbManager.logOut()
let readPermissions: [ReadPermission] = [.publicProfile, .email]
let sdkPermissions = readPermissions.map({ $0.permissionValue.name })
fbManager.logIn(withReadPermissions: sdkPermissions, from: nil) { (result, error) in
if let token = result?.token {
// your token here
}
else {
}
}
Thank you very much. This solved the problem.
1.) The plist file was already set up. I think otherwise the login with Safari wouldn't have worked.
2.) The App Delegate was the reason!!! Small adjustment:
SDKApplicationDelegate.shared didn't work. I should be as followed:
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
(As well in the added "application-open URL"-function.)
But now it works. Thanks a lot.
i think maybe i found an one issue, in my xcode, AppDelegate's
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool , xcode fix this function to private, and i fixed this function to internal, it will works~

Fast App Switch iOS 11 Facebook Login

Currently my facebook login does the following:
Tap the login with fb button
Asks for permission to to use "facebook.com" to log in
Asks whether to use app or log in with an email or phone in a Safari View Controller
If selected app: Asks to open Facebook app
Asks for permission to let the fb app use your to log in
Returns to app
Those are too many steps for me. I'd like to do something like Uber app, it's facebook login flow is:
Tap the login with fb button
Asks to open Facebook app
Asks for permission to let the fb app use your account to log in
Returns to app
Uber's flow:
Facebook Fast App Switch
There's an article that says theres a Fast App Switch way to login which is what I want for my app, If facebook app is installed I want the login to be done directly to the app.
I've used this code at my sign in button action with no luck:
let fbLoginManager = FBSDKLoginManager()
fbLoginManager.loginBehavior = .native
fbLoginManager.logIn(withReadPermissions: ["public_profile", "email"], from: self) { (result, error) in
let credential = FacebookAuthProvider.credential(withAccessToken: accessToken.tokenString)
// Perform login by calling Firebase APIs..
}
At my Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fbXXXXXXXX</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>XXXXXXXX</string>
<key>FacebookDisplayName</key>
<string>My Beautiful App</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>
At my AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions:launchOptions)
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let handled = FBSDKApplicationDelegate.sharedInstance().application(app, open: url, options: options)
return handled
}
Facebook SDK version: 4.27.1
Using FBSDKCoreKit (4.27.1)
FBSDKLoginKit (4.27.1)
FBSDKShareKit (4.27.1)

App Invites facebook | not getting notification on iOS but getting in android however invitation is listed in facebook -> apps -> app invites

I had added facebook app invite feature in my app below is my code sending app invitations
let content = FBSDKAppInviteContent()
content.appLinkURL = NSURL(string: "applinkurl")
content.appInvitePreviewImageURL = NSURL(string: "appInvitePreviewImageURL")
FBSDKAppInviteDialog.showWithContent(content, delegate: self);
I had added below extension to the class
extension FACEBOOKTEXT:FBSDKAppInviteDialogDelegate {
//MARK: FBSDKAppInviteDialogDelegate
func appInviteDialog(appInviteDialog: FBSDKAppInviteDialog!, didCompleteWithResults results: [NSObject : AnyObject]!) {
print("invitation made")
}
func appInviteDialog(appInviteDialog: FBSDKAppInviteDialog!, didFailWithError error: NSError!) {
print("error made")
}
in app delegate :
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
var shouldReturn:Bool = FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation);
shouldReturn = shouldReturn || GIDSignIn.sharedInstance().handleURL(url, sourceApplication: sourceApplication, annotation: annotation);
shouldReturn = shouldReturn || Instagram.sharedManager().handleOpenURL(url);
shouldReturn = shouldReturn || LinkedInBridge.handleURL(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation);
return shouldReturn;
}
I had configured the "App Links" from facebook portal nd put it in infi.plist and content.appLinkURL.
On running this code the app invitations are sent. And when the receiver of the app invitation is on android the invitation is listed in the notification feel of the facebook and use is able to install app via it. But if the receiver of the invitation is on iOS the invitation is not listed in the notification feed of the use however if the user goes to facebook -> More(tab) -> apps -> App invites, here the invitation is listed.
Please guide me where I am doing wrong. and what should I do to list invitations in notification in iOS same like android.
I am using Xcode 6.4 and Swift 1.2
this is working for iOS 8 but not working for iOS 9
Thanks in advance,
add below URL schemes to your info.plist for make it work in iOS 9
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fbapi20130214</string>
<string>fbapi20130410</string>
<string>fbapi20130702</string>
<string>fbapi20131010</string>
<string>fbapi20131219</string>
<string>fbapi20140410</string>
<string>fbapi20140116</string>
<string>fbapi20150313</string>
<string>fbapi20150629</string>
<string>fbapi20160328</string>
<string>fbauth</string>
<string>fbauth2</string>
<string>fb-messenger-api20140430</string>
<string>fb-messenger-platform-20150128</string>
<string>fb-messenger-platform-20150218</string>
<string>fb-messenger-platform-20150305</string>
<string>fb-messenger-api</string>
<string>fbshareextension</string>
</array>
additionally do below two things
1. Open facebook.com -> Settings -> apps -> delete your app if already given permissions to the app
Open mobile facebook app -> tap on More(last tab) -> apps -> app invites -> delete if any app invite is already there.
Hope this will work for you.

Facebook login with Parse in iOS9 and Swift2

I am trying to login with Facebook with Parse in iOS9 but the application keep opening Safari instead of Facebook app in real device. and even in Safari when I try to use the keyboard to enter the email and password of Facebook account the page reload so it's impossible to login and give the permission to the app. The user should open safari and login first in Facebook then open my app and then give permission. I think it's not the best user experience since the user have already a Facebook app.
I have followed all the steps I will list them here:
Add Fraleworks
Link Binaries
Updaded info.plist
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb907580375984874</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>FacebookAppID</key>
<string>907580375984874</string>
<key>FacebookDisplayName</key>
<string>Appname</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fbapi20130214</string>
<string>fbapi20130410</string>
<string>fbapi20130702</string>
<string>fbapi20131010</string>
<string>fbapi20131219</string>
<string>fbapi20140410</string>
<string>fbapi20140116</string>
<string>fbapi20150313</string>
<string>fbapi20150629</string>
<string>fbauth</string>
<string>fbauth2</string>
<string>fb-messenger-api20140430</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>akamaihd.net</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>facebook.com</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>fbcdn.net</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
App Delegate
import UIKit
import Parse
import FBSDKCoreKit
import ParseFacebookUtilsV4
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Parse.setApplicationId("appID", clientKey: "MyKey")
PFFacebookUtils.initializeFacebookWithApplicationLaunchOptions(launchOptions)
return true
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application,openURL: url,sourceApplication: sourceApplication, annotation: annotation)
}
func applicationDidBecomeActive(application: UIApplication) {
FBSDKAppEvents.activateApp()
}
}
Login code:
#IBAction func loginButtonClicked(sender: AnyObject) {
if let _ = FBSDKAccessToken.currentAccessToken() {
print("connected already")
} else {
PFFacebookUtils.logInInBackgroundWithReadPermissions(["public_profile", "email", "user_friends", "user_birthday" , "user_education_history","user_photos"]) {
(user: PFUser?, error: NSError?) -> Void in
if let user = user {
if user.isNew {
print("User signed up and logged in through Facebook!")
} else {
print("User logged in through Facebook!")
}
} else {
print("Uh oh. The user cancelled the Facebook login.")
}
}
}
}
Using a webview to log users in is now the default behaviour of the Facebook SDK for iOS 9 and according to Facebook team, this approach gives a better user experience as it avoids the additional dialogues being shown between app transitions.
In apps that use the newest SDK (v4.6 and v3.24), we will surface a
flow using Safari View Controller (SVC) instead of fast-app-switching
(FAS) because of additional dialog interstitials that add extra steps
to the login process in FAS on iOS 9. Additionally, data that we've
seen from more than 250 apps indicate that this is the best experience
for people in the long run
Read more on Facebook

Resources