Set default value for Parse column when new user registers - swift

I am attempting to make a running app, where the user would register and have their own account on the app. But I am using the default Parse signUpViewController when the user is registering. I have a column in the User class in Parse that is marathons completed. Upon registering the value of that column for a new user is undefined, is there a way I can set a default value for when the user registers? Would this be able to be done in the following section?
func signUpViewController(signUpController: PFSignUpViewController, didSignUpUser user: PFUser) {
self.dismissViewControllerAnimated(true, completion: nil)
}
I am using swift, xcode7 along with parse as my backend.

Use a cloud code beforeSave on the User class to assign default values if it's newly created. Here's an example bit of code to check out.
Parse.Cloud.beforeSave(Parse.User, function(request, response) {
// Check if the User is newly created
if (request.object.isNew()) {
// Set default values
request.object.set("marathonsCompleted", 0);
request.object.set("someBooleanColumn", true);
request.object.set("someStringColumn", "someDefaultString");
}
response.success();
});

Related

How to stop the user from entering the duplicate record on default save

I have a custom module where there is an email field. Now i want to stop the user if the email is already in the database.
I want to stop the user on save button and show the error. Like when a required field goes empty.
I tried to get some help but was not able to understand it.
Note: I realized after posting this that you are using suitecrm which this answer will not be applicable toward but I will leave it in case anyone using Sugar has this question.
There are a couple of ways to accomplish this so I'll do my best to walk through them in the order I would recommend. This would apply if you are using a version of Sugar post 7.0.0.
1) The first route is to manually create an email address relationship. This approach would use the out of box features which will ensure your system only keeps track of a single email address. If that would work for your needs, you can review this cookbook article and let me know if you have any questions:
https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_9.2/Cookbook/Adding_the_Email_Field_to_a_Bean/
2) The second approach, where you are using a custom field, is to use field validation. Documentation on field validation can be found here:
https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_9.2/Cookbook/Adding_Field_Validation_to_the_Record_View/index.html
The code example I would focus on is:
https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_9.2/Cookbook/Adding_Field_Validation_to_the_Record_View/#Method_1_Extending_the_RecordView_and_CreateView_Controllers
For your example, I would imagine you would do something like this:
Create a language key for your error message:
./custom/Extension/application/Ext/Language/en_us.error_email_exists_message.php
<?php
$app_strings['ERROR_EMAIL_EXISTS_MESSAGE'] = 'This email already exists.';
Create a custom controller for the record creation (you may also want to do this in your record.js):
./custom/modules//clients/base/views/create/create.js
({
extendsFrom: 'RecordView',
initialize: function (options) {
this._super('initialize', [options]);
//reference your language key here
app.error.errorName2Keys['email_exists'] = 'ERROR_EMAIL_EXISTS_MESSAGE';
//add validation tasks
this.model.addValidationTask('check_email', _.bind(this._doValidateEmail, this));
},
_doValidateEmail: function(fields, errors, callback) {
var emailAddress = this.model.get('your_email_field');
//this may take some time so lets give the user an alert message
app.alert.show('email-check', {
level: 'process',
title: 'Checking for existing email address...'
});
//make an api call to a custom (or stock) endpoint of your choosing to see if the email exists
app.api.call('read', app.api.buildURL("your_custom_endpoint/"+emailAddress), {}, {
success: _.bind(function (response) {
//dismiss the alert
app.alert.dismiss('email-check');
//analyze your response here
if (response == '<email exists>') {
errors['your_email_field'] = errors['your_email_field'] || {};
errors['your_email_field'].email_exists = true;
}
callback(null, fields, errors);
}, this),
error: _.bind(function (response) {
//dismiss the alert
app.alert.dismiss('email-check');
//throw an error alert
app.alert.show('email-check-error', {
level: 'error',
messages: "There was an error!",
autoClose: false
});
callback(null, fields, errors);
})
});
},
})
Obviously, this isn't a fully working example but it should get you most of the way there. Hope this helps!

How to manage acces control at login

I been looking for control what a kind of user can see in my app, this is a scholar project. I'm using Swift and Firebase Authentication. I have two kinds of users: Model and Client. In my app I have some views for the Model and other for the Client. What I want to do is that once they log in, in to the app show just the views for their kind of user. I don't know how to verify if the user that is trying to sign in is a Model or a Client.
#IBAction func signInTapped(_ sender: UIButton) {
if validateFields(){
Auth.auth().signIn(withEmail: emailTxt.text!, password: passTxt.text!, completion:{
(user, error) in
if let u = user {
//User is found
}else{
//Error
}
})
}
}
I know that the code need to be where is the comment "User is found" but I don't know if I need to modify something into the the Firebase Console
Create a Firebase Database or Firestore to your project.
Now when you authenticate a user you should also create a userobject in your databse. In this object you can create a field to store whether your user is a model or a client.
Now once the user has signed in, you can download this userobject from the database, check whether the user is a model or client, and send the user to their corresponding views.
You can use custom claims.
You set them using the Admin SDK
// Javascript
admin.auth().setCustomUserClaims(uid, {model: true}).then(() => {
// The new custom claims will propagate to the user's ID token the
// next time a new one is issued.
});
Then in client SDK just read the claim.
user.getIDTokenResult(completion: { (result, error) in
guard let model = result?.claims?["model"] as? NSNumber else {
// Something
}
if model.boolValue {
// Show something else
} else {
// Something else again
}
})
Shamelessly copied from Firebase Docs

Parse.com REST API - How to Assign user Id to each installation

I am developing an IONIC2 app and working with Parse's REST API.
My issue is that I want to assign a userID to the current installation in Installation class.
The flow:
The user opens the app, a new installation object is created in the installation class by assigning the following fields:
let deviceInfo = {
"deviceToken":deviceToken,
"installationId":uuid,
"deviceModel":model,
"deviceVersion":version,
"appName":"app",
"appVersion":"1.0.0",
"channels": [
"global"
]
};
Once the user clicks on the sign-up button, a session object is created in the session class and the installationId is by default set to (undefined); however, a userId is assigned to that newly created session object.
My Question:
How can I assign the userID of the newly registered user in Installation class, like it was made automatically in the session class?
Updated answer:
Did you try it with cloud code
Parse.Cloud.beforeSave("_Installation", function(request, response) {
var createdAt = request.object.get("createdAt");
var updatedAt = request.object.get("updatedAt");
if (createdAt.getTime() == updatedAt.getTime()) {
//object didnt exist before, so save the User (pointer to _User class)
request.object.set("user_id", request.user);
response.success();
};
});

Swift & Parse.com find by specific column not ID

Reference: http://blog.parse.com/2014/06/06/building-apps-with-parse-and-swift/
I'm trying to find a columns value: userPassword, based in the userName column. Using the above reference from Parse it shows that to get data from parse you should use:
var query = PFQuery(className: "GameScore")
query.getObjectInBackgroundWithId(gameScore.objectId) {
(scoreAgain: PFObject!, error: NSError!) -> Void in
if !error {
NSLog("%#", scoreAgain.objectForKey("playerName") as NSString)
} else {
NSLog("%#", error)
}
}
However, as you can see it is looking for (gameScore.objectId) - The problem is I do not know this value as the user isnt entering a complex parse generated ID. They're entering their chosen username. In the rows I have userName and Password set. How do I search the rows for the userPassword so I can verify it based on their specified userName.
Thanks in advance
Why are you querying the database for a username and password. Adding a new user is very simple with Parse. Taken directly from their docs:
Query User table on Parse
You can query the user table first, using a PFQuery:
PFQuery *query = [PFUser query];
[query whereKey:#"username" equalTo:username];
Adding New User
The idea of user accounts that let people access their information and share it with others in a secure manner is at the core of any social app. Whether your app creates its own sharing environment or integrates with existing social networks, you will need to add functionality to let people manage their accounts in your app.
We provide a specialized user class called PFUser that automatically handles much of the functionality required for user account management.
First make sure to include our SDK libraries from your .h file:
#import <Parse/Parse.h>
Then add this code into your app, for example in the viewDidLoad method (or inside another method that gets called when you run your app):
func myMethod() {
var user = PFUser()
user.username = "myUsername"
user.password = "myPassword"
user.email = "email#example.com"
// other fields can be set just like with PFObject
user["phone"] = "415-392-0202"
user.signUpInBackgroundWithBlock {
(succeeded: Bool!, error: NSError!) -> Void in
if error == nil {
// Hooray! Let them use the app now.
} else {
let errorString = error.userInfo["error"] as NSString
// Show the errorString somewhere and let the user try again.
}
}
}
This call will asynchronously create a new user in your Parse app. Before it does this, it checks to make sure that both the username and email are unique. It also securely hashes the password in the cloud.
You can learn more about Users, including how to verify emails and handle read and write permissions to data, by visiting our docs.
Run your app. A new object of the class User will be sent to the Parse Cloud and saved. When you're ready, click the button below to test if a User was created.
Further
I created a tutorial about connecting to parse if you still wish to go down the route of querying the server manually:
http://ios-blog.co.uk/tutorials/swift-create-user-sign-up-based-app-with-parse-com-using-pfuser/

iOS 8 Beta Keychain User Access Control

I am looking at the new user access control abilities with the introduction of Touch ID when accessing keychain.
Here's the scenario...
I have written a user secret to the keychain with the new access control object in the Keychain query.
Next time I attempt to return this secret, I will be presented with the Touch ID / Passcode interface as expected.
Next time I attempt to write the same data to the keychain, I want to first check if it already exists.
This also presents the Touch ID interface even if i specify the return data attribute to false. But this is not what I want.
Is this the expected behaviour or am I missing a specific attribute to disable the Touch ID interface?
I think what you are trying to achieve is possible by doing something similar to:
// --- Add this code to your save method
// Adds a new keychain item
let status: OSStatus = SecItemAdd(keychainQuery as CFDictionaryRef, nil)
if status == errSecSuccess {
println("Keychain Add: \(KeychainResultCode(rawValue: status)?.description)")
return true
} else if status == errSecDuplicateItem {
// perform an update
return self.update(key, data: data)
} else {
return false
}
Does the above works for your needs?