How to use Google idToken, accessToken from my hosted server into my app? - swift

Forgive me for my English!
I am using google Rest API client and GIDSignIn to sign in google account for my app.
GIDSignIn.sharedInstance().delegate = self
GIDSignIn.sharedInstance().uiDelegate = self
GIDSignIn.sharedInstance().scopes = scopes
GIDSignIn.sharedInstance().signIn()
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
withError error: Error!) {
if let error = error {
showAlert(title: "Authentication Error", message: error.localizedDescription)
self.service.authorizer = nil
} else {
self.service.authorizer = user.authentication.fetcherAuthorizer()
print("Successs")
}
}
Successfully signed in after using this.
But I want to use idToken and accessToken into my app getting from my hosted server.
By using those token I want to fetch google calendar events.
Please help how can I use tokens which are getting from my hosted server into my iOS app.
Thanks.

Related

Swift Firebase Twitter Login: Unable to get credential

I am implementing Firebase Authentication with Twitter login and I followed the docs but wasn't able to get any response from getCredentialWith. Other SO post on this topic is outdated as most still uses TwitterKit, which has already stopped being supported.
My implementation so far:
//At viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Login", style: .plain, target: self, action: #selector(loginWithTwitter))
#objc func loginWithTwitter() {
print("Login button tapped")
let provider = OAuthProvider(providerID: "twitter.com")
provider.getCredentialWith(nil) { credential, error in
print(2) // <== Not printed
if error != nil {
// Handle error.
print("Err", error)
}
if let credential = credential {
Auth.auth().signIn(with: credential) { authResult, error in
print(3) // <== Not printed
if error != nil {
// Handle error.
print("Err auth", error)
}
if let authResult = authResult {
print(authResult.credential)
}
}
}
}
Oddly, the above code, as copy and pasted from the docs, doesn't seem to return to print 2.
I have ensured that I have done the following:
Added URL schemes to the Info tab
Enabled Twitter sign in on Firebase Authentication
Added the necessary API key and secret key on Firebase Auth
Added callback URL to Twitter developer dashboard
What am I missing?
I managed to solve it by:
Adding a website URL to the authentication settings in Twitter Developer portal
Moving let provider = OAuthProvider(providerID: "twitter.com") to a global variable

Google Classroom API integration with swift

I want to link my iOS app with Google Classroom on swift. My current goal is to be able to get a list of all the courses I am enrolled in.
Here is the code I am currently using
func googleClassroomList() {
//let sharedInstance = GIDSignIn.sharedInstance()
//let handler = sharedInstance
googleClassroomService.apiKey = "AIzaSyBOGamjhRuu45T2jT7Qa3LmtntSwgIxeqo"
let query = GTLRClassroomQuery_CoursesList.query()
query.pageSize = 1000
let classQuery = googleClassroomService.executeQuery(query, completionHandler: { ticket , fileList, error in
if error != nil {
let message = "Error: \(error?.localizedDescription ?? "")"
print(message)
} else {
if let list = fileList as? GTLRClassroomQuery_CoursesList {
self.fileList = list
print("List: \(list)")
}
else {
print("Error: response is not a file list")
}
}
}
)
}
Here is the error message:
Error: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
I don't understand where I attach the OAuth access token, I tried putting it under apiKey but I don't really understand what I am supposed to do. For reference, I am using this auth scope. "https://www.googleapis.com/auth/classroom.courses"
First you have to sign-in using Google, and Google will manage the OAuth 2.0 token for you.
Here you have the instructions:
https://developers.google.com/identity/sign-in/ios/sign-in?ver=swift
Also make sure to set the service.authorizer property when you are actually signed in:
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
withError error: Error!) {
guard let user = user else {
return
}
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.setLoggedOut(loggedOut: false)
self.myClassroom.service.authorizer = user.authentication.fetcherAuthorizer()
self.showClassroomClasses()
}

Unable to pass Facebook User properties to Firebase FIRAuth in Swift 3

I'm using the following function to login a User with a Facebook Token and the Firebase FIRAuth function. There is no error and no print of email property. As if the function wouldn't be called.
var login = FBSDKLoginManager()
#IBOutlet weak var fbBtnPressed: UIButton!
#IBAction func fbBtnPressed(_ sender: AnyObject) {
login.logIn(withReadPermissions: ["public_profile", "email", "user_friends"], from: self) { (FBSDKLoginManagerLoginResult, Error) in
if Error != nil {
print("The login with Facebook don't working. Erro: \(Error)")
} else {
let accessToken = FBSDKAccessToken.current().tokenString
print("Login with Facebook ok. \(accessToken)")
let credential = FIRFacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
FIRAuth.auth()?.signIn(with: credential) { (email, error) in
if (error != nil) {
print("The login in the Firebase broke \(error)")
} else {
print("Login in the Firebase ok \(email)")
}
}
}
}
}
After a lot of research, it seems to be a change in Swift3 in combination with the Keychain swap.
You have to enable the Keychange Sharing in your project under capabilities.

Google Sign-In via Firebase: GIDSignInDelegate does not conform to ViewController

I'm introducing Google Sign-In to my app and whilst both Google and Firebase documentation is thorough enough, what I have done as they suggested is not sufficient... I am still getting this error. Hopefully this will help others with finding a solution to the problem when implementing their SDK....thanks in advance for reviewing this chunky one:
Here's the Firebase guide and the Google guide:
So
Added Google to podfile - CHECK
Added line into Bridging-Header - CHECK
Added GoogleService-Info.plist & bundle identifier & reversed client ID to URL schemes - CHECK
App Delegate has the following, with no errors but I notice there are likely to be conflicts between Facebook login (working correctly) and newly Google, which I've no idea how to handle together:
P.S. I have NOT added GIDSignInDelegate to AppDelegate here because I am planning for my VC to handle the login logic, as you will see below...
LoginVC ViewController code here:
class LoginVC: UIViewController, UIViewControllerTransitioningDelegate, UITextViewDelegate, UITextFieldDelegate, GIDSignInDelegate, GIDSignInUIDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let ref = Firebase(url: "https://MYAPPID.firebaseio.com")
GIDDSignIn.sharedInstance().delegate = self
GIDSignIn.sharedInstance().uiDelegate = self
GIDSignIn.sharedInstance().signInSilently() // for if the user has recently been authenticated
}
Then this, which from what I can see... should be everything Google needs to talk to Firebase:
// Implementing the required GIDSignInDelegate methods
func googleSignIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!, withError error: NSError!) {
if (error == nil) {
// Auth with Firebase
let userId = user.userID
let idToken = user.authentication.idToken
let fullName = user.profile.name
let givenName = user.profile.givenName
let familyName = user.profile.familyName
let email = user.profile.email
ref.authWithOAuthProvider("google", token: user.authentication.accessToken, withCompletionBlock: { (error, authData) in
// User is logged in!
})
} else {
print("\(error.localizedDescription)")
}
}
func googleSignOut() {
GIDSignIn.sharedInstance().signOut()
ref.unauth()
}
// Implement the required GIDSignInDelegate methods and Unauth when disconnected from Google
func signIn(signIn: GIDSignIn!, didDisconnectWithUser user:GIDGoogleUser!, withError error: NSError!) {
ref.unauth()
}
// IBAction to handle the sign-in process
#IBAction func googleButtonPressed(sender: TKTransitionSubmitButton!) {
GIDSignIn.sharedInstance().signIn()
}
Baffled? Sorry for the long one guys...but I've done everything the Firebase guide suggests and that means the logic in the Google doc for AppDelegate is all there in the ProfileVC. Any pointers?
It's saying your class have not implemented required method for your GIDSignInDelegate. There are major change in name of method in Swift 3. So your new method will be
public func sign(_ signIn: GIDSignIn!, didSignInFor user:
GIDGoogleUser!, withError error: NSError!)
Please check Library screen shot. So In is missing in new swift 3 convention of naming of methods or classes.
I found needed methods by typing "func s" and searching in suggestions box
Oh, I miss Alt+Enter feature in Android Studio
(BTW this is for Swift 3 in XCode 8 beta)
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: NSError!) {
let authentication = user.authentication
let credential = FIRGoogleAuthProvider.credential(withIDToken: (authentication?.idToken)!,
accessToken: (authentication?.accessToken)!)
let comp:FIRAuthResultCallback = { (user:FIRUser?, error:NSError?) in
if error == nil {
DataStorage.inst.user.id = user?.uid
}
}
FIRAuth.auth()?.signIn(with: credential, completion: comp)
}
func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: NSError!) {
}
Just replace
func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,
withError error: NSError!) {
if (error == nil) {
// Perform any operations on signed in user here.
} else {
print("\(error.localizedDescription)")
}}
with
public func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
//Code
}
Just add
#import "GoogleSignIn/GoogleSignIn.h"
to your Bridging header file and hit shift + cmd + k to clean.
Go to: Link Binary with Libraries. Then, Click on Add, then Add Other. Press "Cmd + shift + G". Then, type: "/usr/lib". Then, Click on "libz.1.dylib". Press Ok to add and the errors will go away. Also, you are probably not completing all the functions that come along with this protocol. You will have to add following:
func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,
withError error: NSError!) {
if (error == nil) {
// Perform any operations on signed in user here.
} else {
print("\(error.localizedDescription)")
}
}
func signIn(signIn: GIDSignIn!, didDisconnectWithUser user:GIDGoogleUser!,
withError error: NSError!) {
// Perform any operations when the user disconnects from app here.
// ...
}
Also, make sure you have added the foll. line in Bridging Header.
#import <GoogleSignIn/GoogleSignIn.h>
UPDATE:
GIDSignInDelegate can't be added to View Controller. Instead, you should add "GIDSignInUIDelegate" in VC and try to perform other(Gidsigndwlwgate) operations in App Delegate. It will work.

No FB access token upon initial Parse FB login

I am logging into my app using PFFacebookUtils.logInWithPermissions however, the first time I log in the actual login works fine but I get the FB error code = 2500 An active access token must be used to query information about the current user. This results in any graphRequests failing.
If I then recompile the code to the device this error does not occur and all graphRequests work fine. Why is the app not getting an access token upon the first login? Also, if I completely delete the app from the device and reinstall this whole process starts again (error code = 2500 on first attempt).
Also maybe worth noting, this didn't happen with the previous versions of Parse and FB SDKs. I am just starting to move this app into iOS9 and that's when this problem popped up.
Xcode 7.0.1, Parse SDK v1.8.5, FacebookSDKs-iOS-20150910
I was able to resolve this issue by first calling the FBSDK login method followed by the Parse SDK login method (inside the FBSDK callback):
#IBAction func facebookButtonAction(sender: AnyObject) {
// Ensure that PFUser == nil - just in here because I heard it can help with some possible issues
PFUser.logOut()
let permissions = ["public_profile", "email", "user_friends"]
// First, login with FB’s SDK
let login: FBSDKLoginManager = FBSDKLoginManager()
login.logInWithReadPermissions(permissions, handler: {(result: FBSDKLoginManagerLoginResult!, error: NSError!) in
if (error != nil) {
NSLog("Process error")
} else {
if result.isCancelled {
NSLog("Cancelled")
} else {
NSLog("Logged in")
// Then with Parse’s, upon FB login success
PFFacebookUtils.logInWithPermissions(permissions) { (user, error) -> 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.")
//...
}
}
}
}
})
}