How can I check my entire parse database - ios

In order for somebody to login or signup in my application, you must first enter the email address. If you have an account and enter the correct email address it will then take you to another view controller so you can enter your password. If the email address you enter is not in the database, you will have go to through the setup process. If a user enters the email address JohnnyAppleseed#example.com I need the Done button to check and see if that is in and based on that it will take them to the appropriate view controller.
So my question is, how can I check my parse database for the email the user enters without having to do it by getObjectInBackgroundWithId
Function. Is this possible in Parse?

You could do something like this...
func checkOrXEmail() {
var query = PFQuery(className: "_User")
query.whereKey("email", equalTo: self.emailTextField.text.lowercaseString)
query.findObjectsInBackgroundWithBlock { (emails, error) -> Void in
if let emails = emails {
for email in emails {
if email["email"] as! String == self.emailTextField.text.lowercaseString {
//The email is taken
}
}
}
}
}
Hope this helps!
Also if you want to check the validity of the email try this...
if email.text != "" {
if validateEmail(email.text.lowercaseString) {
emailTaken = false
if self.emailTaken == false {
println("Not Taken")
checkOrXEmail()
}
} else {
// Do stuff
}
} else {
// Do stuff
}

Related

How to detect if an email address change was reverted?

I was working on the user profile page of my app and I am allowing the user to change their email address. If the user email address is changed successfully, the data in the firebase database of the particular user will be updated. Also, After successfully changing the email address, firebase will send an email to the user's previous email address (the user email address before it was changed to the new one) asking if it was the actual owner of the account who changed the email address and there will be a link to reset their email. If the user chooses to reset the email (for whatever reason), the user's new email will be changed to the previous email. But the problem is that the data in the database will not be updated, how can I detect this change (email reset) and update the database?
authenticateUserAlert.addAction(UIAlertAction(title: "Done", style: .default, handler: { [weak authenticateUserAlert] (_) in
// Print the user email
let emailTextField = authenticateUserAlert?.textFields![0]
print("Email: \(emailTextField!.text!)")
// Print the user password
let passwordTextField = authenticateUserAlert?.textFields![1]
print("Password: \(passwordTextField!.text!)")
// Re-authenticate the user
let user = Auth.auth().currentUser
let credential = EmailAuthProvider.credential(withEmail: emailTextField!.text!, password: passwordTextField!.text!)
user?.reauthenticate(with: credential, completion: { (result, error) in
if error != nil {
// Alert: What ever the error
print(error!.localizedDescription)
Alerts.errorAlert(on: vc, error: error!.localizedDescription, dismissAlert: false)
} else {
print(result!)
let editProfilePage = EditUserProfile()
editProfilePage.updateUserInfo()
}
})
}))
Here is what I tried according to an answer
Auth.auth().currentUser?.reload(completion: { (Error) in
//Completion handler
if let email = Auth.auth().currentUser?.email {
UserDataRetrieval.userEmail = email
self.emailLabel.text = email
print(Auth.auth().currentUser?.email)
}
})
It depends on the type of authentication you are using but honestly you should just use the email that is part of the authenticated account and then you don't need to worry about updating it in the database.
You can always just get the users email by using Auth.auth().currentUser.email
Update
Found a workaround to the issue of the credential data, try using
Auth.auth().currentUser?.reload(completion: { (Error) in
if (Error != nil) {
//Do something with error
} else {
//Do something with success or do nothing
}
})
Just call update credentials at the start of the app if you want to always have to most up to date credentials
You can always build your own custom handler for the email change revocation landing page. In that landing page you can update your database.
Check the official docs on how to do that.

How to set up Firebase iOS authentication email

Having looked through lots of previous questions and looking on the Firebase website documentation, it keeps leading me back to the snippet of code I need in my VC, BUT not how to actually set it up?.
Firstly in the email address verification setup on Firebase
I've by mistake put my personal email address as the 'reply to' email - do I put my personal (not business) email in there/how would I change it? Apologies for any over the top censoring (not sure what is private and not)
Secondly in my SignUpViewController what do I put as the URL String and what do I put as my IOSBundleID? Many thanks!
To change the email go to Authentication and press templates. There you have some options for your mail.
Press the pen beside noreply#yourfirebase.firebaseapp.com.
There you will have a replay to line and you can change all those settings
This is all you need to register a new user :
Auth.auth().createUser(withEmail: emailText.text!, password: passwordText.text!) {
(user, error) in
if error != nil {
print(error.localizedDescripton)
}else {
print("registration successful")
}
}
To send confirmation email to user make a call after user is created and use this method :
func sendConfirmationEmail() {
// Here you check if user exist
if self.authUser != nil && !self.authUser!.isEmailVerified {
self.authUser!.sendEmailVerification(completion: { (error) in
// Send the email
})
}
else {
// ERROR
}
}
You could now call the second method after user been created and the user will get an email

How to add a username to Firebase database upon registration?

Upon logging in I want my app to make a new field in the Firebase database with the child named after the username.
if let email = emailField.text, let pass = passwordField.text {
// Check if it's sign in or register
if isLogin {
// Sign in the user with Firebase
Auth.auth().signIn(withEmail: email, password: pass, completion: { (user, error) in
// Check that user isn't nil
if let u = user {
// User is found, go to home screen
self.ref?.child(email).childByAutoId().setValue("1")
self.performSegue(withIdentifier: "goHome", sender: self)
print("yes")
}
When I try to do this, it gives me an error called SIGABART which I believe is associated with not having segues connected properly.
Yet if I delete this line:
self.ref?.child(email).childByAutoId().setValue("1")
or change the email field to a random string like "test", it works fine and appears in Firebase.
If I remember correctly, you can't use symbol # in nodes names. It's first problem. You can do it another, I think better, way:
You need to create user to ref like:
/users/uid from created FIRUser.
You can do it with next steps:
For example, your registration page will have 3 UITextFields: userEmail, userLogin and userPassword.
// *1* Create user
FIRAuth.auth()!.createUser(withEmail: userEmail.text!,
password: userPassword.text!)
{ user, error in
if error == nil {
// *2* Then log him in
FIRAuth.auth()!.signIn(withEmail: self.userEmail.text!,
password: self.userPassword.text!)
{ result in
// *3* Create new user in database, not in FIRAuth
let uid = (FIRAuth.auth()?.currentUser?.uid)!
let ref = FIRDatabase.database().reference(withPath: "someStartPart/users").child(uid)
ref.setValue(["uid": uid, "email": userEmail.text!, "login": userLogin.text!, "creationDate": String(describing: Date())])
self.performSegue(withIdentifier: "fromRegistrationToMainPage", sender: self)
}
} else {
print("\(String(describing: error?.localizedDescription))")
}
}
Like this. Hope it helps.
Firebase Auth will not allow you to store such a value. You will need to save this into Firebase Database or another service. e.g. In the Firebase Database:
userRef.setValue("username123")
You should save the username value in the database. Something like this:
FIRdatabase.database().reference().child("yourchildname").updateChild(u)
(Im on my phone, so the call might not be EXACTLY like that, but should be very close)
Cheers.
Swift 4:
//***** for realTime database
let ref = Database.database().reference(fromURL: "https://add your project URL")
let userRef = ref.child("users").child(user.user.uid)
let values = ["Email": email, "UserName": userName] //userName is the name of textField

Add Extra Parse Log In Field

I am making an app that logs you in to a certain group, Currently I have it where you log in as such:
let loginUser = PFUser()
loginUser.username = username.text!
loginUser.password = password.text!
PFUser.logInWithUsername(inBackground: loginUser.username!, password: loginUser.password!, block: { (user, error) in
if user != nil { //Continue with code
but what I'd like to do would be to add in my group login ID field so that I do not have to make an additional call to match their groupID TextField with their currently set up groupID. I don't know if you can and I couldn't find it in documentation. Something Like:?
let loginUser = PFUser()
loginUser.username = username.text!
loginUser.password = password.text!
loginUser["groupID"] = groupID.text!
PFUser.logInWithUsername(inBackground: loginUser.username!, password: loginUser.password!, login["groupID"]: login.groupID block: { (user, error) in
if user != nil { //Now Checks login AND for group id...
Now obviously I know it's not that easy but does anybody have a mildly easy work around for this? Right now afterwords i'm comparing the
user["groupID"] == groupID.text! {
// Then Login to group is a success!
// Segue to next View Controller
} else {
// Let the user know the Log In was "unsuccessful" even though they logged in but they got their groupID wrong
// Log User Out
// Clear groupID Text Field & Display alert so they can reattempt log in
}
Any help would be appreciated!
Thanks!
I suggest you to use "cloud code", you might want to create your own login method using some other language like javascript.

Parse + Facebook Questions

I am trying to implement Parse + Facebook
Here is what I would like to do:
User Log In with Facebook
Login Authorized
A new User created from Facebook properties (gender, age, name, etc)
Below is my code which logs in to Facebook using PFFacebookUtils. The code successfully created a User on my Parse, but I don't have those details of the User from Facebook which I want to use.
I would like to get the user's name, gender, hometown, etc on Facebook.
How do I achieve that??
var permissionArray = ["public_profile","user_friends","email","user_birthday", "user_work_history", "user_education_history", "user_hometown", "user_location", "user_likes"]; on Facebook
PFFacebookUtils.logInInBackgroundWithReadPermissions(permissionArray) { (user: PFUser?, error: NSError?) -> Void in
if user != nil {
if user!.isNew {
println("New User");
}
else {
println("Old User");
}
println(user?.username);
}
else {
println("Login Cancel")
}
}
You need to request the users "me" data, and then you can use that to populate your user object. So, in your if user!.isNew { you'll need to do something along the lines of...
let fbDetailsRequest = FBRequest.requestForMe()
fbDetailsRequest.startWithCompletionHandler { connection, result, error in
if error != nil {
// Handle the error
}
if let graph = result as? FBGraphObject {
// Now you can fill out the data on your user object
user!.setObject(graph.objectForKey("email")!, forKey: "email")
user!.setObject(graph.objectForKey("gender")!, forKey: "gender")
// Don't forget to save afterwards...
user!.saveInBackgroundWithBlock(nil)
}
}
To see the fields you can grab, check out https://developers.facebook.com/docs/graph-api/reference/user If you need anything other than "core" items, you might have to have extra permissions.

Resources