I'm trying to add Firebase Phone Auth to an app that I'm making in XCode. However, I'm having trouble with steps 3 of the firebase documentation and everything after that.
I don't understand where my code is supposed to go. I try some of it already and I attached the image of what I have done so far. Please help.
Thank you.
Ok, the code seems right.
Now you must add another textfield where the user can add the verification code arrived from the SMS.
In a new method triggered by the user after adding the code you must set a FIRAuthCredential like in the code of the example:
FIRAuthCredential *credential = [[FIRPhoneAuthProvider provider]
credentialWithVerificationID:verificationID
verificationCode:newTextField.text!];
And then do the signin with:
[[FIRAuth auth] signInAndRetrieveDataWithCredential:credential
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
if (error) {
// ...
return;
}
// User successfully signed in. Get user data from the FIRUser object
if (authResult == nil) { return; }
FIRUser *user = authResult.user;
// ...
}];
Related
I'm implementing an Authenticate with Firebase using Password-Based Accounts on iOS. After sign-in a user we can get particular information like user.email, user.uid, user.photoURL, user.displayName. However I can set email and password as follows.
[[FIRAuth auth]
createUserWithEmail:username
password:password
completion:^(FIRUser *_Nullable user,
NSError *_Nullable error) {
}];
In here no problem to get user.email. But I didn't set other information here. How to set other information such as user.photoURL, user.displayName with above createUserWithEmail method.
You need to call FIRUserProfileChangeRequest after the user authentication to update the profile info.
FIRUserProfileChangeRequest *changeRequest =
[[FIRAuth auth].currentUser profileChangeRequest];
changeRequest.displayName = userInput;
[changeRequest commitChangesWithCompletion:^(NSError *_Nullable error) {
// ...
}];
Read more on https://firebase.google.com/docs/auth/ios/manage-users
You can check my answer here.
It can help You. But its on Swift language.
Main tip that You need to store Users in database too. And have a link to image in it.
Hope it helps
I am using ObjectiveDropboxOfficial framework for Dropbox integration within Objective-C app (due to the deprecation of v1 dropbox api).
Framework link
I am trying to get logged in dropbox user info (email, name, etc). Here is my code:
DropboxClient *client=[DropboxClientsManager authorizedClient];
[[client.usersRoutes getCurrentAccount]
response:^_Nonnull(DBUSERSBasicAccount *response, DBError *dberror)
{
// loginLabel.text=[NSString stringWithFormat: #"%#\n%#", account.name, account.email];
return response;
}
}];
This code doesn't work and additionnally causes weird error from xcode: enter image description here
The method definition is:
- (DBRpcTask<DBUSERSBasicAccount *, DBUSERSGetAccountError *> *_Nonnull) getAccount:(NSString *_Nonnull)accountId;
- (DBRpcTask<TResponse, TError> *_Nonnull)response:
(void (^_Nonnull)(TResponse _Nullable, TError _Nullable,
DBError *_Nullable))responseBlock;
I was stuck with this for a whole day, any help would be appreciated:
1- How to get user infos using the framework, or
2- What is causing the error and how should that Nonnull method be called?
Thank you in advance
So finally after 2 days of struggling I found the response :
DropboxClient *client = [DropboxClientsManager authorizedClient];
if(client)
{
[[client.usersRoutes getCurrentAccount] response:^(DBUSERSFullAccount *account, DBNilObject *obj, DBError *error) {
if (error != nil) {
NSLog(#"Error %#", error.errorContent);
}
if (account != nil) {
NSLog(#"User's name %#", account.name.displayName);
}
if(self.hud)
[self.hud hideAnimated:YES];
}];
I hope this would save another developer's energy and mental health :)
I'm hoping there's an experienced CloudKit guru out there, but based off my google search queries, I'm not sure if you exist. I think this may be a bug with Apple, but I can't be sure :\
I can save a subscription to my CKDatabase fine, no problems at all.
[publicDatabase saveSubscription:subscription completionHandler:^(CKSubscription *subscription, NSError *error) {
if (error)
{
//No big deal, don't do anything.
}
else
{
[[NSUserDefaults standardUserDefaults] setObject:[subscription subscriptionID] forKey:#"SUBSCRIPTION"];
}
}];
Whenever I change a field in my record, I get a push notification, and everything is happy.
My problem is removing this subscription.
I have tried calling -deleteSubscriptionWithID:completionHandler:
As you can see in the above code snippet, I save off the subscription ID (Have also confirmed it to be the correct subscription ID by calling -fetchAllSubscriptionsWithCompletionHandler:
I passed the subscriptionID in that message, like so:
[publicDatabase deleteSubscriptionWithID:[[NSUserDefaults standardUserDefaults] objectForKey:#"SUBSCRIPTION"] completionHandler:^(NSString * _Nullable subscriptionID, NSError * _Nullable error) {
if( error ) {
NSLog(#"ERROR: %#", [error description] );
}
else
{
NSLog(#"SUCCESS: %#", subscriptionID);
}
}];
But it doesn't delete my subscription:
And no matter what I pass as the subscriptionID, there is no error and I see "SUCCESS" upon "deleting".
...so yeah. Clearly that isn't going to work.
If I manually delete the subscription through the Cloudkit Dashboard, my -fetch call properly notices that and returns an empty array:
So at this point I'm certain that I'm either deleting a subscription incorrectly in code, or it's broken and (not likely) nobody has asked on SO or any other forum that I can find?
I have also tried using a CKModifySubscriptionsOperation
CKModifySubscriptionsOperation *deleteSub = [[CKModifySubscriptionsOperation alloc] initWithSubscriptionsToSave:nil subscriptionIDsToDelete:#[[[NSUserDefaults standardUserDefaults] objectForKey:#"SUBSCRIPTION"]]];
[publicDatabase addOperation:deleteSub];
No results :(
I delete subscriptions using the database.deleteSubscriptionWithID function.
If you want to make sure that the ID is correct you could also first fetch all of them using database.fetchAllSubscriptionsWithCompletionHandler({subscriptions, error in
Then in the completion handler check if it's a valid subscription using: if let subscription: CKSubscription = subscriptionObject
And then delete one or more using: database.deleteSubscriptionWithID(subscription.subscriptionID, completionHandler: {subscriptionId, error in
Here you can see code how I delete all subscriptions:
https://github.com/evermeer/EVCloudKitDao/blob/1bfa936cb46c5a2ca75f080d90a3c02e925b7e56/AppMessage/AppMessage/CloudKit/EVCloudKitDao.swift#L897-897
Assume ref = Firebase(url: "your firebase url").
A child of ref would be childRef = ref.childByAppendingPath("child")
If I have ref.observeAuthEventWithBlock listening for authentication changes at ref, and I then use childRef.removeAllObservers(), the auth observer at ref is no longer listening for changes.
Why is this?
I crafted up a small app to duplicate the issue (ObjC code to follow)
The code to watch for auth'ing is:
[myRootRef observeAuthEventWithBlock:^(FAuthData *authData) {
NSLog(#"got an auth event");
}];
and we have the child node
child = [myRootRef childByAppendingPath:#"child_path"];
then the initial auth is
[myRootRef authUser:#"dude#thing.com" password:#"pw" withCompletionBlock:^(NSError *error, FAuthData *authData) {
NSLog(#"authentication 1 success");
[child removeAllObservers];
[self doAuth];
}
}];
The doAuth method simply auth's another user and outputs 'authentication 2 success'
got an auth event
got an auth event
authentication 1 success
authentication 2 success
So as you can see it worked as advertised - I was unable to duplicate the issue. My guess is the error may lie somewhere else in your code.
I want to write code in AppDelegate.m that checks if PFUser.currentUser credentials are still valid. The reason I am doing this is for this scenario. Assume user logged in successfully and now currentUser has the basic information of that user. If the user changes the password at some time, when application launch, it should check if those credentials are up to date or not. If email & password doesn't match the one in table, it should log the user out.
I tried to do this but apparently PFUser.currentUser.password is always set to null while PFUser.currentUser.email has the actual value of email used to log in. How can I achieve this validation without the password being accessible?
Here is the code I have for guidance:
PFQuery *query = [PFQuery queryWithClassName:#"User"];
[query whereKey:#"objectId" equalTo: PFUser.currentUser.objectId];
[query whereKey:#"password" equalTo: PFUser.currentUser.password];
[query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!object) {
/*Credentials changed! Logout user and request login again*/
NSLog(#"Credentials Changed!");
[PFUser logOut];
[[[navigationController viewControllers] objectAtIndex:0] performSegueWithIdentifier:#"loginSegue" sender:self];
}
else {
/*Credentials are still valid..proceed!*/
NSLog(#"Credentials Correct!");
[[[navigationController viewControllers] objectAtIndex:0] performSegueWithIdentifier:#"skipLoginSegue" sender:self];
}
}];
When this failed I tried to NSLog the password and got null so I understood that this was the problem.
I would write a cloud code function using the master key: Parse.Cloud.useMasterKey();
When you include this in your function you will be able to access/check the user's password and send back a "verified" variable or something of that sort.
Here is my cloud code function to modify a user, but you can easily modify it to verify a user's info. There are also many answers on the parse forums on this as well as lots of info in the docs.
Parse.Cloud.define("editUser", function(request, response) {
//var GameScore = Parse.Object.extend("SchoolHappening");
// Create a new instance of that class.
//var gameScore = new GameScore();
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.get(request.params.myUser, {
success: function(myUser) {
// The object was retrieved successfully.
myUser.set("cabinetPosition", request.params.myPosition);
// Save the user.
myUser.save(null, {
success: function(myUser) {
// The user was saved successfully.
response.success("Successfully updated user.");
},
error: function(gameScore, error) {
// The save failed.
// error is a Parse.Error with an error code and description.
response.error("Could not save changes to user.");
}
});
},
error: function(object, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and description.
}
});
});
If you want to verify your current password, you can store your password locally, then use loginWithUsernameInBackground: to verify. Something like,
[PFUser logInWithUsernameInBackground:[PFUser currentUser].username
password:password
block:^(PFUser *user, NSError *error) {
}];