Twitter login button fail to login - ios

I downloaded some sample code about twitter login code and run it in Xcode, when I run the App, a button appeared in the screen, and when I click it, I cannot login twitter successfully, the code goes to the else path, the code associated with the button is like below:
#IBAction func signInWithTwitter(sender: UIButton) {
Twitter.sharedInstance().logInWithCompletion { session, error in
if session != nil {
// Navigate to the main app screen to select a theme.
self.navigateToMainAppScreen()
// Tie crashes to a Twitter user ID and username in Crashlytics.
Crashlytics.sharedInstance().setUserIdentifier(session!.userID)
Crashlytics.sharedInstance().setUserName(session!.userName)
// Log Answers Custom Event.
Answers.logLoginWithMethod("Twitter", success: true, customAttributes: ["User ID": session!.userID])
} else {
// Log Answers Custom Event.
Answers.logLoginWithMethod("Twitter", success: false, customAttributes: ["Error": error!.localizedDescription])
}
}
}
Has anyone faced this problem? Who can help me out, thanks in advance.

Related

MSAL signout - how to determine if the user selects 'cancel' [Swift]

I am currently using MSAL signout function in my iOS app and have no way of knowing if the user selects 'Continue' or 'Cancel'. Currently, once log out is completed the user is taken back to the root screen of the app. However, I need to be able to stop the flow so that if the user chooses to cancel, they are still on the same screen before choosing the log out option.
private func signout(with account: MSALAccount, signoutParameters: MSALSignoutParameters, completion: #escaping () -> Void) {
self.application.signout(with: account, signoutParameters: signoutParameters, completionBlock: { (result, error) in
if error != nil {
return
}
SharedStorage.authData = nil
completion()
})
}
The issue I have is that result returns true whether the user chooses continue or cancel and error returns nil. Curious if anyone has run into this issue before?

iOS Firebase sign in. Show activity indicator after Google account choosing

I have a ViewController with a Sign in button used to sign in into Firebase with a Google Account:
GIDSignIn.sharedInstance().signIn()
When I click the button, this appears:
Google account choosing
After selecting an account and if the authentication is successful, I want to load a second ViewController. For this, I have a listener in the first ViewController that will sign in again when the authentication state changes, this time successfully, without asking the account again and sending me directly to the second ViewController:
Auth.auth().addStateDidChangeListener({ auth, user in
if let _ = user {
GIDSignIn.sharedInstance().signIn()
}
})
The problem is that I want an activity indicator to be shown when I go back to the first ViewController from the account chooser. Because the app may be there for a few seconds during the authentication process and I don't want the user to tap again the Sign In button, while the first signing in hasn't already finished.
I need a way to recognise that a signing in process is taking place, to show an activity indicator that locks the screen to prevent the user from tapping again Sign in.
WORKAROUND 1
When I click the Sign in with Google button, I set an UserDefaults integer as 1. Then, when the ViewController is reloaded after the Google account chooser, I look for this integer and if it's 1, I don't stop the activity Indicator.
Because I want the activity indicator shown since the user clicks the button until the authentication is completed.
When button is clicked I do:
GIDSignIn.sharedInstance().signIn()
UserDefaults.standard.set(1, forKey: "signingIn")
UserDefaults.standard.synchronize()
In viewWillAppear I do:
if let _ = user {
GIDSignIn.sharedInstance().signIn()
} else {
if UserDefaults.standard.integer(forKey: "signingIn") != 1 {
self.stopActivityIndicator()
} else {
UserDefaults.standard.set(0, forKey: "signingIn")
UserDefaults.standard.synchronize()
}
}
When the authentication is completed, in GIDSignInDelegate there is the function that will be called. In this function, the activity indicator must be stopped:
// The sign-in flow has finished and was successful if |error| is |nil|.
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error;
WORKAROUND 2
I do a put the signIn Google function into a completion handler but it doesn't work:
self.completionHandlerSigIn {
self.stopActivityIndicator()
}
And the function is this:
func completionHandlerSigIn(completion: () -> Void) {
GIDSignIn.sharedInstance().signIn()
}
The problem is that the view is reloaded during the sign in process, after the account choosing. I need a way to recognize that I come from the Google Account choosing screen.
Just show the loading indicator right when the user clicks sign in, then hide it either when the authentication process returns with error or after processing the result. I don't use google sign in, but I can give you my example with Twitter.
#IBAction func onTwitterClicked(_ sender: UIButton) {
AuthManager.shared.loginWithTwitter(self)
}
Here is the loginWithTwitter method in AuthManager:
func loginWithTwitter(_ viewController:BaseController) {
self.provider = .twitter
viewController.showLoadingPanel()
TWTRTwitter.sharedInstance().logIn(completion: {session, error in
guard (error == nil) else {
viewController.hideLoadingPanel()
viewController.showInfoAlert("Oops", error!.localizedDescription, nil)
return
}
let credential = TwitterAuthProvider.credential(withToken: session!.authToken, secret: session!.authTokenSecret)
self.auth.signIn(with: credential, completion: {user, error in
viewController.hideLoadingPanel()
guard error == nil else {
viewController.showInfoAlert("Oops", error!.localizedDescription, nil)
return
}
self.tryConfirmUserInFirestore(user, viewController)
})
})
}

Twitter / Fabric login button not behaving as expected

I have a very simple iOS project where I'm using Twitter/Fabric login button for user login to my app.
I've managed to get the Fabric login button working. When the user clicks on the Twitter login button they are automatically authenticated (that's if they are logged into the Twitter app) otherwise the user is presented with a Twitter login screen.
I'm not sure why the user is automatically authenticated when they are logged into the Twitter app on their phone.
Is there a way to use the Twitter/Fabic API to open the Twitter app and ask for permission to grant access to my app similar to Facebook login even if the user is logged into the Twitter App.
This is what my AppDelegate looks like:
Twitter.sharedInstance().start(withConsumerKey: "someKey", consumerSecret: "someSecret")
Fabric.with([Twitter.self])
This is what my ViewController looks like:
#IBOutlet private weak var twitterLoginButton: TWTRLogInButton!
// and
twitterLoginButton.logInCompletion = {(session, error) in
if error != nil {
print("ERROR: \(error)")
} else {
if let unwrappedSession = session {
print(unwrappedSession.userName)
}
}
}
Twitter.sharedInstance().logIn { (session, error) in
if let unwrappedSession = session {
print("Signed in as: \(unwrappedSession.userName)")
} else {
print("ERROR: \(error)")
}
}
Fabric documentation says that the first default for login is to go through the Twitter app (that may be why your user is automatically authenticated if they're already logged in the app), otherwise it will go through the webAuth login flow.
"To force the log in flow to use the web OAuth flow pass the TWTRLoginMethodWebBased method to the relevant log in methods."
// If using the TWTRLoginButton
let logInButton = TWTRLogInButton() { session, error in
}
logInButton.loginMethods = [.webBased]
So if you want to force the user to go through the web flow, try adding to your code: twitterLoginButton.loginMethods = [.webBased]

How to check whether the user is new user or old user

I have one login screen, which have email, password. And in register screen after user registred they will come to login screen to login.
That time I need to check , if the user is first time user or old user. If first time user means I need to redirect them to my feedback screen. Or old user means I need to redirect them to my home screen. How to do that with firebase?
Her my code for login screen :
#IBAction func loginWithUserNamePassword(){
loginWithMailAndPassword((username.text?.trimWhiteSpace)!, password: (password.text?.trimWhiteSpace)!) { (user, error) in
if error != nil{
KRProgressHUD.dismiss()
SCLAlertView().showError("Login Error", subTitle: error!.localizedDescription)
}
else {
KRProgressHUD.dismiss()
if user!.emailVerified{
currentUser = user
enableSync()
self.callHomescreen()
}
else
{
AlertView().showError("Login Error", subTitle: "This email is has not been verified yet")
}
}
}
}
Or else in my feed back screen there are some text fields. And the model class is :
var feedbackData = [files]()
class files {
// having some string variables
}
By using this, if my data is empty in my feedback screen redirect the user to feedback screen or else redirect them to home screen. Can we do that?
Updated :
if profileData.FirstName.characters.count <= 0 {
print("Home screen calling")
}
else if profileData.FirstName.characters.count > 0 {
print("feedback screen calling")
}
Thought of trying like this. But no use.
If I understand your question currectly, once user is logged in, you want to check the creation date of the use account. To do so you have two options:
The server side. If you are using Firebase database just add the date of creation. Firebase documantation does not offer a method to get the creation date on the app side.
The app side. User user defaults, when the user login in the first time set the date for that user. When you get to the login screen again, check for existance. I would reccomend using the user id as the key.
For example:
Your user just logged in, you want to check if it the first time that he did:
if let displayName = FIRAuth.auth()?.currentUser?.displayName {
//Make sure we have the user
if UserDefaults.standard.bool(forKey: displayName) {
// try to get the user default for the spacific key
let wasConnected = UserDefaults.standard.bool(forKey: displayName)
if wasConnected {
print("This user was connected")
}
} else {
// This user was never connected
// We set the default to his ID
UserDefaults.standard.set(true, forKey: displayName)
UserDefaults.standard.synchronize()
}
}
To use the date, I think the easiest way is to convert the date to string.
Fiddle with the code to do exactly what you want.

How to test if my facebook friendlist function is working in swift

I found a piece of code here on stack overflow which I use to find the facebook friend list of the current user in my app.
Now I want to test that code but, due to the version 2 restrictions I can't find any of my friends because my app is still in development and nobody can use my app. So I cannot find any using friends.
How can I test my friendlist functionality?
I was just dealing with the same problem that you have and it's as WizKid says:
https://developers.facebook.com and login to your account
Go into your app then click the "Roles" tab then the "Test Users" tab
Click "Add" and this window will come up. Authorize the user for your app and add the permissions you want them to give your app.
To add friends just click the "Edit" button then "Manage this test User's friends". Add the friends you want the user to have. (Convenient autocomplete is included for other test users)
After you do the former steps I suggest you also change the test user's name and make them a password. The password can be the same for all your test users. You should also login as the test user ("Edit" again) and change their profile picture to differentiate between them especially if you're using profile pictures.
Here is the annoying part; to be able to see (in your app) the test user's friends that you just set, you have to repeat the following for each of the friends you want to see in your list of facebook friends. (This is assuming that you're not getting "invitable friends")
Reset your simulator
Login using the test user's email and password in the safari popup
Repeat No 7, 8 for every test user (This is to make the friends "facebook friends that have used the app")
Good luck and don't drive yourself crazy :) Hope this helps
Another fix is that the problem may be the login function. Because after I've added the right permissions to my test friend it still failed.
I got it working but the main problem seemed to be my login functions. I wasn't using the FBSDKLoginManager. This was easily implemented by:
func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
println("User Logged In")
if ((error) != nil)
{
// Process error
}
else if result.isCancelled {
// Handle cancellations
}
else {
// If you ask for multiple permissions at once, you
// should check if specific permissions missing
if result.grantedPermissions.contains("email")
{
self.performSegueWithIdentifier("loggedIn", sender: self)
//self.returnUserData()
// Do work
}
}
}
func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
println("User Logged Out")
}
And then
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//if (FBSDKAccessToken.currentAccessToken() == nil)
//{
// User is already logged in, do work such as go to next view controller.
// self.performSegueWithIdentifier("loggedIn", sender: self)
// self.returnUserData()
//}
//else
//{
let loginView : FBSDKLoginButton = FBSDKLoginButton()
self.view.addSubview(loginView)
loginView.center = self.view.center
loginView.readPermissions = ["public_profile", "email", "user_friends"]
loginView.delegate = self
//}
// Do any additional setup after loading the view.
}
This fixed my problem completely after giving the test friend permission.

Resources