Anonymously login auto generated user - ios

I see that objectId of users generated locally and users created after anonymous login are not the same.
For example
PFUser.enableAutomaticUser()
let localUser = PFUser.currentUser()!.objectId!
print(localUserId) // "obj1"
PFAnonymousUtils.logInWithBlock {
(user: PFUser?, error: NSError?) -> Void in
let annonUserId: String = PFUser.currentUser()!.objectId!
print(annonUserId) // obj2
}
I want that obj1 to persist throughout the anonymous login phase.
Can I somehow "attach" the locally created user and login him anonymously? or is auto generated users are only useful for when you later upgrade him to a user&pass / social based logins ?

PFAnonymousUtils.logInWithBlock is defined to destroy existing anonymous user data and create a new clean anonymous user. You should only do that when the user is logged out.
If you enable anonymous users then one will be created initially and you can add whatever details you want to that. Then, later, when the user wants a real account use signUp: on the PFUser to convert it.
Note that anonymous users aren't real, you can't use them for everything. So, you may have some issues with them actually participating with other users. If this is the case then you may need to create real placeholder users with auto-generated login details and convert that at a later date by updating the username and sending a forgotten password e-mail (or similar).

Related

How can I use user input to name a child in Firebase?

I'm trying to create a simple user database on Firebase for iOS. I have two textfields, one that takes the user's email address, and the other that takes the user's password. I want the email to be the user's uid. I try to accomplish this by creating a variable called "email" which I set equal to emailTextField.text! Then I implement the code that generates child(s) in Firebase, like so:
ref = Database.database().reference()
ref.child("users").child(email).setValue(true)
Here's my problem: creating a child and naming it using a variable, doesn't work. I can do the following just fine:
ref.child("users").child("email")
but once I take away the quotation marks around "email" so that it becomes the variable, the program crashes.
How can I use user input to name a child in Firebase?
Firebase node / document names do not support the same character set which email addresses support, for example, the . symbol in an email address would make the child name invalid.
If you tried setting a child as
ref.child("users").child("xyz#xyz.xyz")
you should see the same error.
If you absolutely need to use the email address as the node name, I recommend encoding the email in a way which is compatible with the firebase node name rules.
Link to the rules
Edit: If you are using firebase auth, the normal pattern is too use the UID returned by the authenticated user object as the node name, not the email address entered from the textfield.
A quick example:
Auth.auth().signIn(withEmail: email, password: password) { (user, error) in
if let user = user {
ref.child("users").child(user.uid).setValue(true)
}
}

How to make app (with username/password login) know that a user is logged in?

I'm trying to make a login screen and made a database with Firebase by Google. The way I tried to make accounts in database is just by making a new child which is "Users" and then the next child would be a user (which is uniquely defined with a unique username). Then, user has other attributes and an attribute called loggedIn which is set to String 'false' but when on loginScreen login goes successfully set to String 'true'. How can I know after login and when that LoginViewController goes away which account has logged in exactly on that phone (simulator at the time) because there can be more users at one time with the attribute value 'loggedIn' set to 'true' and because of that can't go back to database to check that. I'm really new at this and don't know if this whole approach is okay by making in real-time database something like that and actually checking that by the attribute. Maybe I have to use some kind of a local database or something similar?
Swift 4, iOS development, Xcode 9
If you just want to persist locally the login status you may use UserDefaults. Just have a key called currentUser and set the value as his unique Id.
Once a user logs out just clear that key.
You can also use that to determine whether to launch the login screen when the app opens.
But it may be better to use something like AWS Cognito or similar services to handle user management.
Are you building an iOS app only or a cross-platform project?
I'm not sure this is the perfect answer for you. However, some of my apps use CloudKit and the login is authenticated and only then opens up areas of the app on the user's device. I'm sure if you wanted to check the status of successful logins, the authentication on the cloud could update as confirmation and you could subsequently access the cloud database using the CloudKit Dashboard.
It's quite intuitive and works seamlessly with Xcode.
I have a class called LoginManager, defined as an NSObject. Included in there is an optional String variable called accessToken with setter and getter functions for saving and retrieving my access token, including an option for clearing the token which would be used upon logout. There is also a function to check the status of the key.
var accessToken: String? {
get {
return //key from storage
}
set {
if newValue == nil {
//remove key from storage
} else {
//save key to storage
}
}
}
func isUserLogedIn() -> Bool {
return self.accessToken != nil
}
In my own case, I have an application manager object that changes the root view controller based on this info.
LoginManager.singleton.isUserLogedIn() ? loadMainView() : loadLoginView()
So the resulting view controller is never loaded unless the user is logged in. Is that useful to you?

Can't get list of users [duplicate]

This question already has answers here:
How do I return a list of users if I use the Firebase simple username & password authentication
(7 answers)
Closed 6 years ago.
I want to show list of users in my app. I use default Auth system from firebase. But response always empty.
FIRDatabase.database().reference().child("users").queryOrdered(byChild: "email").observe(.value, with: { snapshot in
print(snapshot)
})
But snapshot is always Snap (users) <null>
The Firebase Authentication system does not automatically insert anything into the Firebase Database. I guess your database is empty, which is the reason for snapshot being null.
Your code looks correct, but as I said there might not be any data in your database to receive.
Depending on what exactly you want to achieve you should consider storing user meta data in you database. A good point to do so would be directly after the user creation.
Registering a user with Firebase Authentication, by default, does nothing to modify your Firebase Database. Authentication and Database are two pretty much unrelated services. It's a common practice, once you register a user, to save an entry in your Database with their uid, so you can relate the two services:
let auth: FIRAuth? = FIRAuth.auth() // The authentication object
auth?.createUser(withEmail: email, password: password) { (user, error) in
// If registration was successful, `user` is a FIRUser with a uid
if let userId = user?.uid {
let exampleDBPath = FIRDatabase.database().child("users").child(userId)
// Write the user object, for instance a user name or other data, to this path
exampleDBPath.setValue(someJSONAboutTheUser) { (error, result) in
// Now you have a spot to modify your user in the database
}
}
}
This FIRUser created from registration is the same type of object you'll get when a user tries to sign in, so you can find the correct user in the database via the same uid.

Checking if a value has been in the user class has been created Parse Server Swift

In a project I am working on the user goes through a sing up process. In the process a user is created using their entered username and password, if that succeeds then a fullName, and accountVerified is added to the current user with its corresponding value.
The problem is if the user quits the application before the save is complete then the image, fullName, and accountVerified is not added to the current user.
This causes a problem later when the application is relaunched. When the app is relaunched it checks for a user, if there is a user then it checks of if their accountVerified value is true or false. Since the user quit before the save completed there is no accountVerified to check as acountVerified and its value were not added to the user.
To account for this I will save the users fullName, and accountVerified to NSUserDefaults and when the app is launched check if those are created and given a value. If not then use the NSUserDefault values will be used to set the values and save to the current user.
The Question:
I use Parse Server with Heroku and mLab mongoDB. I am wondering what the best way to check the current users object to see if accountVerified, and fullName have been created. Any help is much appreciated!
Query user with 'where' accuntVerified = True; set1 Query user with 'where' accountVerified = False; set2 If the user does not exist in set1 or set2, accountverified is not set.

Getting data only when logged in

In my app i have some functions: login, getNews, getWeather. The last two functions can be executed only if the user is logged in. I don't want to login everytime also if the user is already logged in, so if the two lasts functions returns a not logged in error i want to login and then executed the queue of functions that required the login.
That's only an example, the real code is much longer and the functions that depends on login are more than two. I want to know the best solution to manage that situation.
For example, you can store in UserDefaults state of logged in user or not. And base on this call any functions you want.
When the user has logged in you can store his credential in the keychain.
Look here for a brief tutorial:
Tutorial One
Tutorial Two.
Then you can check every time if you have his credentials stored and log in automatically, and then perform the functions getNews and getWeather.
To store data between your app launches, you can try any of the following two methods :
1) The very simple solution would be to store the user data in your UserDefaults in the form of user dictionary.
for ex. NSUserDefaults.standardUserDefaults().setObject(userDict, forKey: #"User Dictionary"). This can be painful if your userDict is large or difficult to make.
2) The other solution can be, use a archiver to store the user data. You can make your custom archiver from this link.
So when user success login use NSUserDefaults logged value = 1
Example;
Add prefs with that codes.
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
Success login after set logged object inside 1.
let logged = 1
prefs.setObject(logged, forKey: "logged")
And check user if logged or not logged show login
You can add under below check logged codes everywhere inside project
if prefs.valueForKey("logged") as! Int == 1 {
}else{
// go login
}
For logout you can use ;
let logged = 0
prefs.setObject(logged, forKey: "logged")
Thanks

Resources