Swift Facebook Login sdk error with code 2 - swift

I am getting an error while logging in with Facebook. And it was working about 3-4 months ago.
Now I am back at developing this app again and I changed the development target to iOS 13.0 from iOS 12.0 and add the SceneDelegate and other necessary things. Actually, I don't think this is the reason but good to mention.
Now I am getting this error:
FBSDKLog: Cannot login without a valid login configuration. Please
make sure the LoginConfiguration provided is non-nil Error
Domain=com.facebook.sdk.core Code=2 "(null)"
UserInfo={com.facebook.sdk:FBSDKErrorDeveloperMessageKey=Cannot login
without a valid login configuration. Please make sure the
LoginConfiguration provided is non-nil}
while running this:
fbLoginManager.logIn(permissions: ["email, public_profile"], from: self) { (loginResult, error) in
if error != nil {
print(error!)
}
if let currentToken = AccessToken.current {
let credential = FacebookAuthProvider.credential(withAccessToken: currentToken.tokenString)
Auth.auth().signIn(with: credential) { (authResult, error) in
if let error = error {
let authError = error as NSError
print(authError)
} else {
DispatchQueue.main.async {
self.setupTabbar()
self.dismiss(animated: true, completion: nil)
}
}
}
}
}
I checked info.plist several times and apply the instructions from scratch but I am still getting this error.
I am using XCode 12.5 and Swift 5
Edit: When I remove the permissions it works but I actually need those permissions.

Solution
I changed permissions from ["email, public_profile"] to:
["email", "public_profile"]
so it looks like this:
fbLoginManager.logIn(permissions: ["email", "public_profile"], from: self) { (loginResult, error) in
if error != nil {
print(error!)
}
if let currentToken = AccessToken.current {
let credential = FacebookAuthProvider.credential(withAccessToken: currentToken.tokenString)
Auth.auth().signIn(with: credential) { (authResult, error) in
if let error = error as NSError? {
print(error)
} else {
DispatchQueue.main.async {
self.setupTabbar()
self.dismiss(animated: true, completion: nil)
}
}
}
}
}

Related

(Firebase) After login with facebook, it won't return to my app

When I log in with Facebook in on a Real Device It will be stuck on the Facebook login page and don' return back to my app.
I have put facebook code in URL Schemes and put all code that need to put in info.plist.
This is all the code that i use to login Facebook by using firebase.
In Viewdidload
facebookButton.addTarget(self, action: #selector(handleCustomFBLogin), for: .touchUpInside)
Code that i use in Viewcontroller.
#objc func handleCustomFBLogin(sender:UIButton!){
LoginManager().logIn(permissions: ["email", "public_profile"], from: self) { (result, error) in
guard let result = result else {
print("No result found")
return
}
if result.isCancelled {
print("Facebook Login Cancelled")
} else if let error = error {
print("Process error \(error.localizedDescription)")
} else {
print("Logged in")
self.showEmailAddress()
self.actionfb()
}
}
}
func loginButton(_ loginButton: FBLoginButton, didCompleteWith result: LoginManagerLoginResult?, error: Error?){
if(error != nil){
print(error!)
return
}else{
print("Successfully Logged in using facebook")
showEmailAddress()
}
}
func actionfb(){
let accessToken = AccessToken.current
guard (accessToken?.tokenString) != nil else {return}
let credential = FacebookAuthProvider.credential(withAccessToken: accessToken!.tokenString)
// Perform login by calling Firebase APIs
Auth.auth().signInAndRetrieveData(with: credential) { (authResult, error) in
if let error = error {
self.showAlert(title: "error", message: "\(error.localizedDescription)")
return
}
self.performSegue(withIdentifier: "GoGo", sender: nil)
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
}
func showEmailAddress(){
GraphRequest(graphPath: "/me", parameters: ["fields" : "id, name, first_name, last_name, email, birthday, picture"]).start { (connection, result, err) in
if(err != nil){
print("Failed to start GraphRequest", err ?? "")
return
}
print(result ?? "")
}
}
func loginButtonDidLogOut(_ loginButton: FBLoginButton){
print("Logged out of Facebook")
}
In Appdelegate
ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
This will happen only when i had test on real device!!, but in simulation this can work normally
I'm not exactly sure if this is the solution, but this fixed it for me.
I copied the OAuth redirect URI from my firebase, under Authentication -> Facebook
And then on my Facebook developer page, under Products -> Facebook Login -> Settings, I pasted it into Valid OAuth Redirect URIs
I then logged in by entering in my username and password into of clicking "Login with Facebook" and the error stopped happening.
I have no idea if the error will return, maybe this will be helpful to someone though.

Is there a way to use Firebase with a ShareExtension without AppGroups

I'm setting up a shareExtension in iOS and want to use the FirebaseSDK to upload data direct instead of using AppGroups. This works as expected, but after 1 hour the UserToken get's invalidated and i can't reach the Firestore Backend anymore.
I'm using the FirebaseSDK (6.2.0) and enabled Keychain sharing to access the current signedIn User. I have the same Google-Plist in the MainApp and the shareExtension. The data gets also uploaded correctly from the shareExtension and was also updated via the snapshotListener in the MainApp.
Relevant code in the MainApp
lazy var db = Firestore.firestore()
//TEAMID form the Apple Developer Portal
let accessGroup = "TEAMID.de.debug.fireAuthExample"
override func viewDidLoad() {
super.viewDidLoad()
do {
try Auth.auth().useUserAccessGroup("\(accessGroup)")
} catch let error as NSError {
print("Error changing user access group: %#", error)
}
guard let user = Auth.auth().currentUser else {
self.statusLabel.text = "user get's lost"
return
}
statusLabel.text = "UserID: \(user.uid)"
// Do any additional setup after loading the view.
db.collection("DummyCollection").addSnapshotListener { (querySnapshot, error) in
if let err = error {
print(err.localizedDescription)
}
guard let snapshot = querySnapshot else {
return
}
DispatchQueue.main.async {
self.dbCountLabel.text = "\(snapshot.count)"
}
}
}
func signIN(){
// https://firebase.google.com/docs/auth/ios/single-sign-on
do {
try Auth.auth().useUserAccessGroup("\(accessGroup)")
} catch let error as NSError {
print("Error changing user access group: %#", error)
}
Auth.auth().signInAnonymously { (result, error) in
if let err = error{
print(err.localizedDescription)
return
}
print("UserID: \(Auth.auth().currentUser!.uid)")
}
}
}
}
Code in the shareExtension:
override func viewDidLoad() {
super.viewDidLoad()
if FirebaseApp.app() == nil {
FirebaseApp.configure()
}
do {
try Auth.auth().useUserAccessGroup(accessGroup)
} catch let error as NSError {
print("Error changing user access group: %#", error)
}
tempUser = Auth.auth().currentUser
if tempUser != nil {
userIDLabel.text = "UserID: \(tempUser!.uid)"
doneButton.isEnabled = true
db.collection("DummyCollection").addSnapshotListener { (querySnapshot, error) in
if let err = error {
print(err.localizedDescription)
}
guard let snapshot = querySnapshot else {
return
}
DispatchQueue.main.async {
self.dataCountLabel.text = "\(snapshot.count)"
}
}
} else {
// No user exists in the access group
self.navigationItem.title = "No User"
}
}
I expect that this should be possible, but the Token gets somehow invalid in the MainApp and i could not reach the Firestore backend.
6.2.0 - [Firebase/Auth][I-AUT000003] Token auto-refresh re-scheduled in 01:00 because of error on previous refresh attempt.
6.2.0 - [Firebase/Firestore][I-FST000001] Could not reach Cloud Firestore backend. Connection failed 1 times. Most recent error: An internal error has occurred, print and inspect the error details for more information.
Answering my own question: This should be fixed in the next release (Firebase 6.4.0) Details can be found in this PR 3239.

A (swift) project is crashing when cancel facebook authentication

My project use Firebase and Facebook Authentication. It works fine, but when I choose to cancel the Facebook Authentication (the first time when i fetch the uid) the project crash.
Here is the method i use:
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
let credential = FacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
Auth.auth().signInAndRetrieveData(with: credential) { (user, error) in
// [START_EXCLUDE]
if let error = error {
print(error.localizedDescription)
return
}
self.uid = Auth.auth().currentUser?.uid
self.firstFetch()
// [END_EXCLUDE]
}
print("logged in")
}
Can Anyone help me, please?
Ok, the whole implementation of this function was wrong, because it was fetching the user no matter if it was authenticated or not. Here is the new method I wrote:
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result:
FBSDKLoginManagerLoginResult!, error: Error!) {
if error != nil {
print("look a at your.. errm.. code, please", error.localizedDescription)
} else if result.isCancelled {
print("houston, we have a situation: the player cancelled the auth request")
} else {
let credential = FacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
Auth.auth().signInAndRetrieveData(with: credential) { (user, error) in
self.uid = Auth.auth().currentUser?.uid
print("you're in, remember: with great power comes great responsibility!")
self.firstFetch()
}
}
}

How can I detect if the user was deleted from Firebase auth?

Two apps are in the same Firebase project. One app deleted a user from Firebase Auth. But another app still get user uid from somewhere, maybe cache, and access the data in Firebase database with Auth's uid too.
I mean I can still get "user.uid" by let user = FIRAuth.auth().currentUser, if keeping sign-in.
The apps both set FIRDatabase.database().persistenceEnabled = true.
I would like to sing out or refresh cache at all apps if the user was deleted from Auth accordingly.
You can achieve it by doing this inside appDelegate:
//Check if user does exists
func checkUserAgainstDatabase(completion: #escaping (_ success: Bool, _ error: NSError?) -> Void) {
guard let currentUser = Auth.auth()?.currentUser else { return }
currentUser.getTokenForcingRefresh(true) { (idToken, error) in
if let error = error {
completion(false, error as NSError?)
print(error.localizedDescription)
} else {
completion(true, nil)
}
}
}
And you can do something like this after checking with the above function in didFinishLaunchingWithOptions:
If user does exist:
self.window?.rootViewController = self.storyboard?.instantiateViewController(withIdentifier: "CustomTabBarViewController")
else:
self.window?.rootViewController = self.storyboard?.instantiateViewController(withIdentifier: "WelcomeViewController")
And to test if it did work simply remove user manually from the Auth manager in the Firebase Console. So like this it should just show the welcome screen if user has been deleted.
with Firebase 4.0 it would look like this:
func checkUserAgainstDatabase(completion: #escaping (_ success: Bool, _ error: NSError?) -> Void) {
guard let currentUser = Auth.auth().currentUser else { return }
currentUser.getIDTokenForcingRefresh(true, completion: { (idToken, error) in
if let error = error {
completion(false, error as NSError?)
print(error.localizedDescription)
} else {
completion(true, nil)
}
})
}

Firebase Facebook login: An invalid API Key was supplied in the request

Trying to get Facebook login to work with the new Firebase, but I keep getting this error: "An invalid API Key was supplied in the request."
facebookLogin.logInWithReadPermissions(["public_profile", "email", "user_friends"], fromViewController: self) { (login, error) in
if error != nil {
print("Facebook login failed. Error \(error)")
} else if login.isCancelled {
print("Facebook login was cancelled.")
} else {
let accessToken = FBSDKAccessToken.currentAccessToken().tokenString
let credential = FIRFacebookAuthProvider.credentialWithAccessToken(accessToken)
if let user = FIRAuth.auth()?.currentUser {
user.linkWithCredential(credential) { (sup, error) in
if let error = error {
print(error.localizedDescription)
return
}
}
} else {
FIRAuth.auth()?.signInWithCredential(credential) { (user, error) in
if let error = error {
// ERROR COMING FROM HERE
print(error.localizedDescription)
return
}
}
}
}
}
Follow the instructions from Google: https://support.google.com/cloud/answer/6158862?hl=en to get or create the API KEY of your iOS App.
Then you need to grab this API KEY and put it in the GoogleService-Info.plist as the:
Key: API_KEY
Value: the api key that you got.