com.facebook.sdk.core error 8 - ios

This is more informative than anything. I couldn't for the life of me find anything on error code 8 when trying to access the login prompt (aka safari) when debugging my ios app. After I hit the log into facebook button in my app it would attempt to open safari then dump me back to the login page to my app. The error was being caused by the permissions array. I had the the permission "public_profile" spelled "public profile" which was throwing an error obviously. So make sure your permission are type corrected if you get the com.facebook.sdk.core error 8.
Hope that helps someone.

Make sure your permissions are typed correctly
func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
if error == nil {
println("login complete")
self.performSegueWithIdentifier("showLogin", sender: self)
}else{
println(error.localizedDescription)
//com.facebook.sdk.core error 8.
}
}

In my case this error was caused by improper bundle id set in facebook settings of the app itself. Facebook "bundle id" is case sensitive, in my Info.plist I had uppercase product name, but in fb settings - lowercase.

In my case, I was using a Facebook account that hadn't yet been added to any of the Facebook app's admins/developers/testers roles.

In my case, after spending several hours of debugging I found that I was using the API,
func application(application: UIApplication,
openURL url: NSURL, options: [String: AnyObject]) -> Bool {
if #available(iOS 9.0, *) {
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: options)
} else {
// Fallback on earlier versions
}
return true
}
which is deprecated for iOS 9.So, I used:
func application(application: UIApplication,
openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
return true
}
Which worked for me. Hope this saves time of someone.

MAN!!! In my case it was the "bio" in the parameter that was causing this error. Facebook has changed the "bio" key to "about". So anyone using "bio" in parameters should change it to "about"
Pheww!!!

In my case It was wrong version. Instead of version: "v2.7", I used version: "2.7"

In my case it was because I listed name twice in the fields array. Assume that would apply to any field requested twice.

I had the same problem. It was because I didn't implement facebook login feature. After adding that, I logged in and my problem got solved.

In my case, I was playing with the Facebook Ads API and I tried to get a field but the name was wrong.
I had insights{date_start,date_end}, instead of insights{date_start, date_stop}.
More info here.
Hope it helps anyone.

In my case, I tried to get Facebook Id without logging into Facebook. Make sure you're logged into Facebook.
let accessToken = FBSDKAccessToken.current()
if accessToken != nil {
self.getCurrentUserFbId()
print("LoggedIn")
} else {
print("Not loggedIn")
self.loginIntoFacebook()
}
Hope this will helpful for anyone.

When it happened to me, I found that Facebook's access token was expired. Someone decided to store access token in UserDefaults and reuse it later. Of course all tokens more than ~2 months old were expired.

In my case it was because of GraphRequest.
The error response is
"com.facebook.sdk:FBSDKErrorDeveloperMessageKey" = "Syntax error
\"Expected end of string instead of \"%\".\" at character 5:
email%2Cname%2Cgender%2Cpicture";
"com.facebook.sdk:FBSDKGraphRequestErrorCategoryKey" = 0;
"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorCode" = 2500;
"com.facebook.sdk:FBSDKGraphRequestErrorHTTPStatusCodeKey" = 400;
"com.facebook.sdk:FBSDKGraphRequestErrorParsedJSONResponseKey" = {
body = {
error = {
code = 2500;
"fbtrace_id" = AFEUYbcYP39;
message = "Syntax error \"Expected end of string instead of \"%\".\" at character 5: email%2Cname%2Cgender%2Cpicture";
type = OAuthException;
};
};
code = 400;
};
The issue about that is https://github.com/facebook/facebook-swift-sdk/issues/309

In my case was because of birthday,friendlists . removing them started to work.

For me just had to go facebook developer under platform and activate deep linking

In our case we were seeing this issue while trying to log in with some test account (but not all). We were not following Facebook's recommended practice:
Before you test each use case below, make sure you remove your app from your test user's Facebook account using app settings.
After we did it for the failing test accounts, we were able to log in.

Related

Testing passwordless auth in Firebase test lab for iOS

I am trying to figure out how to perform e2e test via firebase test lab for iOS that allow to check passwordless authentication flow, which essentially should do following
Enters email within my app
Firebase sends auth link to such email
Somehow I need to be logged into such email somewhere in firebases test device, I assume either in mail app, or gmail?
I need to know when new email arrives and open it
Once I opened an email I need to click on auth link
This should bring me back into the app and authenticate
My biggest issue at the moment is figuring out steps that happen outside my app i.e. how can I prepare for this test and log in under my email address (is it better to log into gmail in safari for example or somehow add this acc to apples mail app?).
Testing email
In my experience, testing your own code to see if an email was sent is not straightforward beyond checking if the method call you expect to send the email has happened.
Add on top of that using Firebase, which does not expose its underlying email send code, and that looks like a challenge to me.
In terms of testing, I suggest you assert that your method calls to send email happened or that the relevant code path was reached. In Firebase web, this looks like:
firebase.auth().sendSignInLinkToEmail(email, actionCodeSettings)
.then(function() {
// The link was successfully sent. Inform the user.
// Save the email locally so you don't need to ask the user for it again
// if they open the link on the same device.
window.localStorage.setItem('emailForSignIn', email);
// TODO save email to something accessible in your iOS tests
// TODO In your tests, confirm that email was saved after it was sent
})
.catch(function(error) {
// Some error occurred, you can inspect the code: error.code
});
See: https://firebase.google.com/docs/auth/web/email-link-auth#send_an_authentication_link_to_the_users_email_address
Another option:
You could setup a test user with an email address on a mail server that you manage, and check for incoming mail for that test user with your own custom mail reading code.
I would use Firebase Admin tools for this: https://firebase.google.com/docs/auth/admin/manage-users#create_a_user
I think you should first take a look at firebase docs for iOS on how to create dynamic links that you can use for email auth.
https://firebase.google.com/docs/auth/ios/email-link-auth
https://firebase.google.com/docs/auth/ios/passing-state-in-email-actions#configuring_firebase_dynamic_links
After you're done with those two check out the following code:
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
// [END old_delegate]
if handlePasswordlessSignIn(withURL: url) {
return true
}
}
func handlePasswordlessSignIn(withURL url: URL) -> Bool {
let link = url.absoluteString
// [START is_signin_link]
if Auth.auth().isSignIn(withEmailLink: link) {
// [END is_signin_link]
UserDefaults.standard.set(link, forKey: "Link")
(window?.rootViewController as? UINavigationController)?.popToRootViewController(animated: false)
window?.rootViewController?.children[0].performSegue(withIdentifier: "passwordless", sender: nil)
return true
}
return false
}
This is just an example on how you can handle the deep link in your app after the user taps the link. The delegate method
func application(_ application: UIApplication, open url: URL,
sourceApplication: String?, annotation: Any) -> Bool
in AppDelegate is used for all deep links into an app. You could set up for example your own scheme that your app conforms to. And you can send url type links with your custom scheme into your app from the browser for example.
To do this just Open Xcode, go to Project Settings -> Info, and add inside ‘The URL Types” section a new URL scheme. Add something of the sort of com.myApp in order for it to be as unizue as possible. Then you can just type into a browser com.myApp://main and handle that in the appDelegate.
Edit: It says so in their docs that you can present a prompt inside the app for the user to input the email. Where the user opens his email from isn't really your concern as long as your dynamic link is set up properly.

Firebase : Facebook authentification with Firebase token not working

I'm trying to get working Facebook authentification in my app.
I'm following instructions here : https://firebase.google.com/docs/auth/ios/facebook-login
When I clicked on the Facebook login button, everything is working fine : the user is logged. In the facebook login delegate method, it is ok :
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!)
In this method, I have to create a Firebase token to authenticate finally with Firebase (step 5). This is what I do :
let credential = FacebookAuthProvider.credential(withAccessToken:
FBSDKAccessToken.current().tokenString)
Auth.auth().signIn(with: credential) { (user, error) in
if let error = error {
print(error.localizedDescription)
self.errorServer()
} else {
FitUtils.setFitUser(user: user)
}
}
The problem : My credential variable is not nil, everything is working, but when i'm calling Auth.auth().signIn(...), the method throwns the error variable, and user is nil.
I don't have many information about the error :
An internal error has occurred, print and inspect the error details
for more information.
And
error NSError domain: "FIRAuthErrorDomain" - code: 17999 0x0000604000640630
I suspect an error about the Facebook API key or something like that in the Firebase console, but I already checked everything is fine.
Any idea ?
EDIT
I found an explicit description of the error :
UserInfo={FIRAuthErrorUserInfoDeserializedResponseKey={
code = 400;
errors = (
{
domain = global;
message = "Unsuccessful debug_token response from Facebook: {\"error\":{\"message\":\"(#100) You must provide an app access token or a user access token that is an owner or developer of the app\",\"type\":\"OAuthException\",\"code\":100,\"fbtrace_id\":\"GkGVPPBP7vo\"}}";
reason = invalid;
}
);
message = "Unsuccessful debug_token response from Facebook: {\"error\":{\"message\":\"(#100) You must provide an app access token or a user access token that is an owner or developer of the app\",\"type\":\"OAuthException\",\"code\":100,\"fbtrace_id\":\"GkGVPPBP7vo\"}}";
}}}}
(lldb)
Finally found an answer thanks to this post :
https://github.com/firebase/FirebaseUI-iOS/issues/83#issuecomment-232523935
I have to disable the option "Is App Secret embedded in the client?" in the Facebook console :
Hope this helps.
On the Facebook Developer site, navigate to:
Settings > Advanced > Security > Require App Secret
Set to YES.
Fixed it for me.
The following worked for me:
Go to android/app/src/main/res/values/strings.xml. Make sure you have the following line in your <resources>:
<string name="facebook_app_id">FACEBOOK*APP*ID</string>
where FACEBOOK*APP*ID is the your app ID from developers.facebook.com/apps
In my case, there was set wrong App secret in Firebase 🤷🏻‍♂️
Go to the Firebase console and choose the project.
Under Project shortcuts choose Authentication.
Select Sign-in method tab.
In Sign-in providers click on Facebook to edit.
Set the correct App secret from your Facebook app.

"Invalid Token" when trying to authenticate phone number using firebase

This is my code:
import FirebaseAuth
class AuthPhoneNum {
static func getPhoneNum(phoneNumber: String) {
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber) { (verificationID, error) in
if let error = error {
print(error)
return
}
UserDefaults.standard.set(verificationID, forKey: "authVerificationID")
}
}
static func verify(verificationCode: String?) {
guard let verificationID = UserDefaults.standard.string(forKey: "authVerificationID") else { return }
if verificationCode != nil {
let credential = PhoneAuthProvider.provider().credential(
withVerificationID: verificationID,
verificationCode: verificationCode!)
Auth.auth().signIn(with: credential) { (user, error) in
if let error = error {
print(error)
return
}
}
} else {
print("No verification code")
}
}
}
This is what the console prints out:
Error Domain=FIRAuthErrorDomain Code=17048 "Invalid token."
UserInfo={NSLocalizedDescription=Invalid token.,
error_name=INVALID_APP_CREDENTIAL}
What am I doing wrong? Thanks
I was also experiencing this problem. Checked the following:
Correct bundle Id
Correct Google-Info.plist
Correct aps-environment value
Correct APNS token type when calling auth.setAPNStoken (.unknown for auto detect)
Nothing helped until in Firebase app settings I uploaded the APNS authentication key (p8) instead of certificates - I used those certificates before for push notifications only and everything was working fine but for phone number notifications something went wrong.
It is most likely that you need to upload an .p8 Key file
(I have an Enterprise account but same thing for developer)
In Apple Developer Account:
All Keys
Create New Key (+)
Type in Global name for all of your apps
Checkbox next to Apple Push Notifications service (APNs)
Download your p8 file
Upload to firebase dashboard
First regenerates APNS key and upload in firebase for cloud messaging
1) Import Firebase and FirebaseAuth
import Firebase
import FirebaseAuth
2) In didFinishLaunchingWithOptions Configure firebase.
FirebaseApp.configure()
3) Write these two func in AppDelegate.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let firebaseAuth = Auth.auth()
firebaseAuth.setAPNSToken(deviceToken, type: AuthAPNSTokenType.prod)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
let firebaseAuth = Auth.auth()
if (firebaseAuth.canHandleNotification(userInfo)){
print(userInfo)
return
}
}
Very Important note : uthAPNSTokenType set correctly for [sandbox / production] or set for common .unknown
In my case it was the apns token type that was wrong:
Auth.auth().setAPNSToken(deviceToken, type: AuthAPNSTokenType.prod)
should have been:
Auth.auth().setAPNSToken(deviceToken, type: AuthAPNSTokenType.sandbox)
In my case, the problem was an incorrect bundle id in the iOS app, in the firebase project settings (Project settings -> General -> Your apps).
I hope this helps anyone overlooking the same detail.
same problem questions have been before on SO. so would like to tell you setup all pre-require step before run code.
Pre-Require Steps:
Register bundle id on Developer account and enable notifications for
bundle id.
Register same bundle id on firebase console setting page and create
app, download Google-Info.plist file, make sure name should be same.
Upload Push certificates on firebase console for sandbox as well as
development.
follow this below link for code implementation.
setup code for Firebase Auth
Make sure that it is APNs that you are selected under Key Services. The number of APNs certificates per developer account is limited to 2. So if you already had 2 certificates before, there is a chance that you are created the certificate by checking DeviceCheck instead of APNs.
For any one else who double checked the above and still have issues, don't forget to add your team ID and App Id in your ios config file.
And, don't forget to download it again, and replace your old one with the updated one.
If you have tried adding the APNs key (p8) in your Firebase console and also checked for the Correct bundle Id and Correct Google-Info.plist.
And still the issue persists
Do check if you have "Push Notifications" enabled and "Remote notifications" selected in "Signing and capabilities" in Xcode->Runner but are not actually using firebase messaging
Then care to uncheck "Remote notifications" from "Signing and capabilities" and remove "Push Notifications" in Xcode->Runner.
In my case this was the issue
I faced same problem when I want send OTP and get notifications, I created APN key on apple developer console then added it to firebase after that everything got well:
If you did everything right as per the documentation. Try one thing.
Paste this line in AppDelegate.m under,
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[[FIRAuth auth] setAPNSToken:deviceToken type:FIRAuthAPNSTokenTypeProd];

Parse facebook login issue?

I am trying to implement facebook login using Psrse.
The following code works if the user has facebook login in their iOS settings, but if they don't it doesn't work.
As soon as I call logInWithPermissions safari opens facebook, and my delegate gets called with nil user, and nil error. When user logins on safari, it takes the user back to the app, application:openURL:sourceApplication gets called, but the completion of logInWithPermissions never gets triggered
Been spending 3 days trying to resolve this. Any suggestions would be appreciated. I already added all keys to info.plist as well
there is a duplicate here that doesn't solve the issue: iOS/Swift: PFFacebookUtils.logInWithPermissions returns nil user and error
let permissionArray = ["public_profile", "email"]
PFFacebookUtils.logInWithPermissions(permissionArray) { user, error in
println(user)
println(error)
}
Appdelegate
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
FBAppCall.handleDidBecomeActiveWithSession(PFFacebookUtils.session())
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String, annotation: AnyObject?) -> Bool {
return FBAppCall.handleOpenURL(url, sourceApplication: sourceApplication, withSession: PFFacebookUtils.session())
}
EDIT:
Added this to application:openUrl:sourceApplication and all values are there and valid after login.
println(url)
println(sourceApplication)
println(PFFacebookUtils.session())
The code causing the issue was this.
Session doesn't exist already so calling close was causing a crash when opening safari with no exception logs. Then coming back to the app it would start the app from scratch, but since it would go back to the login page it was hard to tell.
Need to check to see if session exists or not before calling clode.
func applicationDidEnterBackground(application: UIApplication) {
PFFacebookUtils.session().close()
}

iOS linkedin authentication

I started developing an app for iOS in Swift. Now I am at the part where I need to create a login system. However we need the LinkedIn information from people.
How can I use the OAuth2 API in iOS to achieve this?
I already created an app in the LinkedIn developers area, but now I am stuck. I got some advice from someone that I need to use the UIWebView but I have no clue how this works.
Integrating LinkedIn Login in a Swift application
First, download the LinkedIn iOS SDK. I'll be using the 1.07 stable version for this example. I'll be following the integration guide here.
Create a new Developer Application.
Add your iOS app's Bundle Identifier to your LinkedIn App under Mobile.
Add your LinkedIn app Id and URL Scheme to your app's Info.plist file.
Whitelist the specified LinkedIn URL schemes and ATS URLs.
Copy the linkedin-sdk.framework library to your application. Make sure "copy files if necessary" and "create groups for folder references" are selected.
Project setup complete, now let's write some code!
Create a new Header file called BridgingHeader.h. Under Targets -> YourApp -> Build Settings -> Swift Compiler - Code Generation, add MyApp/BridgingHeader.h to "Objective-C Bridging Header."
In your BridgingHeader.h, add these two lines:
#import <Foundation/Foundation.h>
#import <linkedin-sdk/LISDK.h>
In your AppDelegate.swift, add this code to handle the OAuth URL callback:
Swift 3:
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
if LISDKCallbackHandler.shouldHandle(url) {
return LISDKCallbackHandler.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
}
return true
}
Swift 2.x:
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
if LISDKCallbackHandler.shouldHandleUrl(url) {
return LISDKCallbackHandler.application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
}
return true
}
Now it's time to log in the user. In your view controller, say you have a "Login" button. Your IBAction might look like this:
#IBAction func doLogin(sender: AnyObject) {
LISDKSessionManager.createSessionWithAuth([LISDK_BASIC_PROFILE_PERMISSION], state: nil, showGoToAppStoreDialog: true, successBlock: { (returnState) -> Void in
print("success called!")
let session = LISDKSessionManager.sharedInstance().session
}) { (error) -> Void in
print("Error: \(error)")
}
}
When logging in, the user will be asked to authenticate with your application:
If the user allows, the success block will be called, and you can get information about the authenticated user. If the login fails or the user does not allow access, then the failure block will be called, and you can alert the user on the issue that occurred.
To get information about the user we authenticated with, call a GET request on the user's profile:
let url = "https://api.linkedin.com/v1/people/~"
if LISDKSessionManager.hasValidSession() {
LISDKAPIHelper.sharedInstance().getRequest(url, success: { (response) -> Void in
print(response)
}, error: { (error) -> Void in
print(error)
})
}
The response.data will contain information on the authenticated user:
"{\n \"firstName\": \"Josh\",\n \"headline\": \"Senior Mobile Engineer at A+E Networks\",\n ... }"
Read the docs further for more things you can do with the API.
A sample project (with my App ID obfuscated) can be found here.
LinkedIn is an interesting beast, since their mobile SDKs have two flaws:
An end user NEEDS the LinkedIn app to be installed, otherwise the "login" button will redirect the user to the App Store.
The mobile access token cannot be used on the server. See this screenshot from LinkedIn's iOS documentation
So while JAL's answer is sufficient, you may want to look into implementing LinkedIn's authorization_code OAuth flow in your mobile app instead of the LinkedIn SDK. This would look roughly like the following flow:
The app will redirect the user to your webserver.
The webserver begins the LinkedIn authentication flow, and redirects the user to LinkedIn.
The user logs into LinkedIn, and gets redirected back to your webserver.
The webserver reads the response, and exchanges the Authorization Code with LinkedIn for an access token.
The webserver redirects your user back to the app, using a custom url scheme to send it the LinkedIn access token.
The app uses the LinkedIn access token to login to Stormpath.
Sound complicated? It's actually more straightforward than it seems. I actually wrote some demo code for this flow using Express.js & Swift. This example ultimately sends the access token to Stormpath to ultimately authenticate the user, but you can always replace it with your own code that calls the LinkedIn REST API to grab the profile's information.
In Swift 3.0, UIApplicationOpenURLOptionsKey should be add for Facebook and LinkedIn.
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
if LISDKCallbackHandler.shouldHandle(url)
{
return LISDKCallbackHandler.application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: nil)
}
else
{
return FBSDKApplicationDelegate.sharedInstance().application(app, open: url
, options: options)
}
}
I know this has already been answered but I faced this issue as well and had done everything set in the Accepted answer, but for whatever reason the code still was not hitting success or failure. It turned out that with iOS 9 the following is deprecated.
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
The solution was to use this instead :
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<NSString *,
id> *)options
For example, you could do:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options {
if ([LISDKCallbackHandler shouldHandleUrl:url]) {
return [LISDKCallbackHandler application:app openURL:url sourceApplication:options[UIApplicationLaunchOptionsSourceApplicationKey] annotation:options[UIApplicationLaunchOptionsAnnotationKey]];
}
return YES;
}
Update for Edward Jiang's answer; changes is token access on server + mobile side. Source: https://developer.linkedin.com/docs/ios-sdk-auth
As #Edward Jiang already explained, LinkedIn turns the whole authentication process very clumsy due to the requirement of having the LinkedIn app installed. I wrote a Swift library that handles the authentication flux within an embeded WKWebView: LinkedInAuth-Swift.
This library even eliminates the necessity of handling LinkedIn's response in a server. The WKWebView instance which is presenting the authentication flux is in charge of capturing the authorization code returned by LinkedIn and subsequently requesting the access token.

Resources