Persistent login on most important app - android

I was wondering how the most used apps keeps the login?
When I open Facebook, Twitter, Instagram or 500px my apps are ready without no time of login and I need to know the how-to for my apps, who request 8-10 seconds to login and download the user list.
EDIT: I'm not talking about the "cookie" for credentials. If you try Facebook, for example, you can see that the first login took 30 seconds, and then it is always connected. The other time you open Facebook, it doesn't ask for credentials for Shared Preferences, but it doesn't take 30 seconds to login. Why?

I believe all the Above posts are accurate but i wanted to add my two cents. When your application launches you should make a call in your Launcher Activity (activity that launches when your app icon is clicked on home screen if its not already open) to
// This will get you an instance of your applications shared preferences.
SharedPreferences preferences = getBaseContext().getSharedPreferences("MyPrefs", SharedPreferences.MODE_PRIVATE);
// Values
String userName = preferences.getString("username",null);
String password = preferences.getString("password",null);
// Then you want to query preferences for values such as username and password like
if((userName != null) && (password != null))
{
// **** Log your user into your application auto**Magically** ********
// ------------------- Option 1 - web request -------------------
// First i Would make the initial Web Request before trying to send my User into
// a new Activity.
// Run an `AsynchTask` against your webservice on the server if this is something
// you need to do to see if the username and password, are correct and registered
//---------- Option 2 - Check the SQLite Database(if you are using one) ---------
// Otherwise you can use this info to read from an SQLiteDatabase on your device.
// To see if they are registered
// This is where you would create a new intent to start
// and Login your user, so that when your application is launched
// it will check if there are a username and password associated to the
// Application, if there is and these are not null do something like
// Create a new Intent
Intent automagicLoginIntent = new Intent(getBaseContext(),AutomagicLogin.class);
// Pass the Bundle to the New Activity, if you need to reuse them to make additional calls
Bundle args = new Bundle();
args.putString("username", userName);
args.putString("password", password);
automagicLoginIntent.putExtra("UserInfo", args);
// Launch the Activity
startActivity(automagicLoginIntent);
}else{
// Show the Layout for the current Activity
}
This should be done in your onCreate(Bundle savedInstanceState); method but that is the short of it. It should not be too tricky to implement but the implementation is dependent on how your logic works.
Do you read from SQLIte Database ?
Do you read from WebService ?
etc.
But this should be all you need, unless you need to store some other values in the prefs.
Side Note
All the code above will not work if you have no way of getting this information from the user in the first place, i.e. a registration form.
When thinking of registration, you can initially store these values with the following code:
// Inside an Listener , get a reference to your `TextView`s that were used to enter
// username and password
TextView usernameText = (TextView) findViewById(R.id.textViewUsername);
TextView passwordText = (TextView) findViewById(R.id.textViewPassword);
// Get a reference to the SharedPReferences, SO WE CAN BEGIN TO STORE THE VALUES ENTERED
SharedPreferences preferences = getBaseContext().getSharedPreferences("MyPrefs", SharedPreferences.MODE_PRIVATE);
// Need this to Edit Preferences
SharedPreferences.Editor editor = preferences.edit();
// Then you can add the values
editor.putString("username",usernameText.getText().toString().trim());
editor.putString("password",passwordText.getText().toString().trim());
// Must Call this to write values to the Preferences
editor.commit();
And that should be all you need, to initially store the values and read them back from preferences to automagically login your user each time ur application is launched if it has not been opened, if it has been opened android activity lifecycle should reload the current activity that was last paused.
Good Luck!

You should save an authentication token for each user, you don't need to explicitly reauthenticate every time the user opens the app. When the app makes subsequent API calls, use that authentication token and send it to your back-end. If the back-end tells you that your authentication is invalid, then you know you need to reauthenticate.

They store the token using sharedPreferences
http://developer.android.com/reference/android/content/SharedPreferences.html

Related

How to direct user from a splash activity to the main activity

I am asked to develop an Android application whose description is this:
Let’s assume if you like Football or Cricket so much and you can find
some unknown having the same interests.
You can send Hello to him/her and can chat as well. Fantastic. Let’s
Jump into the Project Ideas
You can Select the Interest from the menu
Find the person with the common interests and send him Hello request
You can get so much information about your interests.
Chat with Friends
You can build this App using Android Studio.
So I have made a splash screen, register, login page and a user setup activity till now.
I have also designed a dashboard type interface which would display various kinds of interest for the user to choose from. So I would have to make a different main activity for different interests, like if the user chooses sports as interest, the main activity would be different than for the user who choses singing as his/her interest.
What do I do if I want to direct the user from the splash screen to the main activity screen (sports, singing, etc.) of his/her choice? (Example code would be appreciated.)
You can use Shared Preference for this.
Just save your interest in preferences with some tag when you select it like below:
SharedPreferences sharedPreferences = getSharedPreferences("MySharedPref",MODE_PRIVATE);
SharedPreferences.Editor myEdit = sharedPreferences.edit();
myEdit.putString("name", name.getText().toString());
myEdit.putInt("age", Integer.parseInt(age.getText().toString()));
myEdit.apply();
myEdit.commit();
Then you can get it on Splash screen from shared preference like:
// Make sure to use the same name while getting data that you use while saving it.
SharedPreferences sh = getSharedPreferences("MySharedPref", MODE_APPEND);
String S1 = sh.getString("name", "");
int A = sh.getInt("age", 0);
You can now use S1 and A variables for whatever you want.
In your case, you can use if/else or switch.

Closing the app and reopening it in the activity I want, without doing it all over again

I can not understand a thing.
I am creating an android app that is connected to the DB.
When the user registers after login, once he is logged in, if he closes the application and reopens it, he makes it all over again.
I want that when the user reopens the app if he has not done the Logout he must be in the activity of the Login.
Can you advise me what to use?
The SharedPreference?
Apps like Facebook, Instagram and other things use?
PS. They are many users.
Thank you very much for helping.
You can use SharedPrederence for session management of Login/Signup :
When User login Hit API or Internal DataBase with validation & get all user details & store it in SharedPreferences.
Next time when User again open app first it will check the status of sharedPreference if login get Data otherwise Login screen will come.
When User Logout Crear all Login Data.
Initialization :
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
Editor editor = pref.edit();
Storing Data :
editor.putBoolean("login_status", true); // Storing boolean - true/false
editor.putString("name", "string value"); // Storing string
editor.putInt("user_id", "int value"); // Storing integer
editor.commit(); // commit changes
Retrieving Data :
pref.getString("name", null); // getting String
pref.getInt("user_id", 0); // getting Integer
Reference : https://www.androidhive.info/2012/08/android-session-management-using-shared-preferences/

Can I make Firebase use a username login process?

I want to make a system which allows for username login. This process requires the following:
User must register with an email/password
The user can set a unique username
The user can sign in with either email or username
The user can recover their password via email or username
The functionality must work on a persistence enabled database
This question has been answered previously, but it disabled the functionality for the user to use password recovery. They also didn't address case-sensitivity, one person could register as "scooby" and another as "Scooby".
DISCLAIMER: This code is now over two years old. While this doesn't mean it's deprecated, I would strongly recommend investigating alternative methods before assuming this is the best approach. I personally wouldn't want the standard login process for Firebase to be dictated by my initial approach to a problem while Firebase wasn't as heavily adopted as it is now.
After multiple iterations of development I've come up with the following design to address this. I will post my code snippets in Swift, but they will typically be translatable directly into Android with ease.
Create a Firebase registration process for email/password.
This is required as the backbone of the user's sign-in experience. This can be implemented completely from the stock Firebase API documentation provided here
Prompt the user to enter their username
The username entry should be completed at registration, I'd recommend an additional field in the registration flow. I also recommend checking if the user has a username whenever they log in. If they don't, then display a SetUsername interface that prompts them to set a username before progressing further into the UI. A user might not have a username for a few reasons; it could be revoked for being rude or reserved, or they might have signed up prior to the username being required at registration.
Make sure that if you're using a persistence-enabled Firebase build that you use Firebase Transactions. The transactions are necessary, otherwise your app can make assumptions about the data in the username table, even though a username might have been set for a user only seconds earlier.
I would also advise enforcing the username to be nearly alphanumeric (I allow for some harmless punctuation). In Swift I can achieve this with the following code:
static var invalidCharacters:NSCharacterSet {
let chars = NSMutableCharacterSet.alphanumericCharacterSet()
// I add _ - and . to the valid characters.
chars.addCharactersInString("_-.")
return chars.invertedSet
}
if username.rangeOfCharacterFromSet(invalidCharacters) != nil {
// The username is valid
}
Saving the user data
The next important step is knowing how to save the user's data in a way that we can access it in the future. Below is a screenshot of the way I store my user data:
A few things to note:
The usernames are stored twice, once in usernames and again in details/[uid]/username. I recommend this as it allows you to be case sensitive with usernames (see the next point) and it also allows you to know the exact database reference to check a username (usernames/scooby) rather than having to query or check through the children of details to find a username that matches (which would only become more complicated when you have to factor in case-sensitivity)
the usernames reference is stored in lowercase. When I check the values in this reference, or when I save to this reference, I ensure that I only save data in lowercase. This means if anyone wants to check if the username 'scoobY' exists, it will fail because in lowercase it's the same username as the existing user "Scooby".
The details/[uid]/username field contains capitals. This allows for the username to display in the case of preference for the user, rather than enforcing a lowercase or Capitalised word, the user can specify their name as "NASA Fan" and not be converted over to "Nasa Fan", while also preventing anyone else from registering the username "NASA FAN" (or any other case iterations)
The emails are being stored in the user details. This might seem peculiar because you can retrieve the current user's email via Firebase.auth().currentUser.email?. The reason this is necessary is because we need references to the emails prior to logging in as the user.
Logging in with email or username
For this to work seamlessly, you need to incorporate a few checks at login.
Since I've disallowed the # character in usernames, I can assume that a login request containing an # is an email request. These requests get processed as normal, using Firebase's FIRAuth.auth().signInWithEmail(email, password, completion) method.
For all other requests, we will assume it's a username request. Note: The cast to lowercase.
let ref = FIRDatabase.database().reference()
let usernameRef = ref.child("users/usernames/\(username.lowercaseString)")
When you perform this retrieval, you should consider if you have persistence-enabled, and if there's a possibility that a username could be revoked. If a username could be revoked and you have persistence-enabled, you will want to ensure you retrieve the username value within a Transaction block, to make sure you don't get a cached value back.
When this retrieval succeeds, you get the value from username[username], which is the user's uid. With this value, you can now perform a retrieval on the user's email value:
let ref = FIRDatabase.database().reference()
let usernameRef = ref.child("users/details/[uid]/email")
Once this request succeeds, you can then perform the standard Firebase email login with the email string you just retrieved.
The exact same retrieval methods can be used to retrieve an email from a username to allow for password recovery.
A few points to be wary of for advanced functionality:
- If you allow the user to update their email using FIRUserProfileChangeRequest, make sure you update it both on the auth AND the details[uid]email field, otherwise you will break the username login functionality
- You can significantly reduce the code required to handle all the different failure cases in the retrieval methods by using success and failure blocks. Here's an example of my get email method:
static func getEmail(username:String, success:(email:String) -> Void, failure:(error:String!) -> Void) {
let usernameRef = FIRDatabase.database().reference().child("users/usernames/\(username.lowercaseString)")
usernameRef.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
if let userId = snapshot.value as? String {
let emailRef = FIRDatabase.database().reference().child("users/details/\(userId)/email")
emailRef.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
if let email = snapshot.value as? String {
success(email: email)
} else {
failure(error: "No email found for username '\(username)'.")
}
}) { (error) in
failure(error: "Email could not be found.")
}
} else {
failure(error: "No account found with username '\(username)'.")
}
}) { (error) in
failure(error: "Username could not be found.")
}
}
This success/failure block implementation allows the code I call in my ViewControllers to be much cleaner. Å login calls the following method:
if fieldText.containsString("#") {
loginWithEmail(fieldText)
} else {
// Attempt to get email for username.
LoginHelper.getEmail(fieldText, success: { (email) in
self.loginWithEmail(email)
}, failure: { error in
HUD.flash(.Error, delay: 0.5)
})
}

Parse: How to add object to the user, who is not not the current user

i have created my app, in which I have created several users. The challenge is, I need to construct the app in a way that, while I am logged in as a user (say User A), I can add input an object into another user (say User B). So, while am logged in as user A, I can input the data that will be saved into one of the empty field, of User B. Can you assist which way, I can arrange this? In short, how can I create an object to associate with the User B.
Here is the thing, while I am logged in as User A, I want to add "Scores" for both user A and B. for instance, if the user A's score is 7, and B's score is 20, I could add the scores while logged in the activity A, and they will be added in the field "Scores" of the corresponding users.
you should go for parse cloud code which is written in java script
refer this link to know more
https://parse.com/docs/js/guide#cloud-code
then you just edit main.js
deploy and call that cloud code from your code
// Use Parse.Cloud.define to define as many cloud functions as you want.
// For example:
Parse.Cloud.define("updateTable", function(request, response) {
var currentUserId=request.params.currentLoggedinUser;
var userToBeUpdatedId=request.params.userToBeUpdated;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userToBeUpdatedId });
user.addUnique("followers",currentUserId);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
deploy this code using comand "parse deploy" from terminal.
call this code from your code like
ParseCloud.callFunction("updateTable", params);
i hope it will help.
The way that Parse is setup by default is so that only the current users data can be editted in the User table. You could probably change the settings for the table however, this could cause security issues.
What I would suggest would be to create a 'Scores' tables. There you could have a row for each user. with a 'userID' column which contained the objectId of the user to reference the user. You could then have a score column which you could update whenever you wanted.
Alternatively to storing the objectId of the user in the userID column you could make an association between the Scores row and the user. See the Parse documentation for how to create associations. https://parse.com/docs/android_guide#users-associations

Parse.com enter more informations for sign in

I am creating an android application for school which let people sign in, for this i used Parse.
My activities for signing in are in this way:
- the first activity, the student enter the email address and passeword and retape passeword, when he push the button, parse verify the email if it doesn't exist if the signing in is secusseful the second activity start.
-The second activity containt text field to complete the profil (FirstName, LastName, Age....).
In Parse.com :
In the Users class I've add new columns (FirstName, LastName,Age...)
My problem is that when the user complete the profil and accept, the data of FirstName, LastName...etc will be add in the Users class of Parse.com to complete the row of the current user signing in.
I've used in the second activity SignInBackground but it bug caus it demand a username (wich is already entered in the first activity), I also used SaveInBackground and also ParseObject but it create a new class.
I'm assuming you're calling signUpInBackground(SignUpCallback callback) in your first Activity.
Here's the Parse documentation about that method:
public void signUpInBackground(SignUpCallback callback)
Signs up a new user. You should call this instead of ParseObject.save() for new ParseUsers. This will create a new ParseUser on the server, and also persist the session on disk so that you can access the user using ParseUser.getCurrentUser().
A username and password must be set before calling signUp.
This is preferable to using ParseUser.signUp(), unless your code is already running from a background thread.
Parameters:
callback - callback.done(user, e) is called when the signUp completes.
So, what you can see is that this method both registers the user with Parse and logs in the user, persisting that login session to disk.
Therefore, when you get to your next Activity, you have no need to sign up or log in. You can simply get the new values from the user and then access the current user (ParseUser.currentUser()), adding the values to that object in a manner like this:
ParseUser user = ParseUser.currentUser();
user.put("attribute1", "value1");
user.put("attribute2", "value2");
user.put("attribute3", "value3");
user.put("attribute4", "value4");
// And so on...
user.saveInBackground(); // You might want to implement a SaveCallback there
FYI: The saveInBackground() method is inherited from ParseObject.
If I am understanding your problem correctly it is that you don't have the data available for the username when you are calling saveInBackground in Activity 2. If this is the case I think the best option would be to pass the data you need (username etc) in the intent when you load the second activity.
To add the username to the intent you would do something like this.
String usernameText = "";
Intent ii=new Intent(Activity1.this, Activity2.class);
ii.putExtra("username", usernameText);
startActivity(ii);
Then to retreive the username in OnCreate method of Activity 2 you would do something like:
Intent iin= getIntent();
Bundle b = iin.getExtras();
if(b!=null)
{
String username =(String) b.get("username");
}
Obviously in my solution, I have assumed that you will retrieve the username from an EditText, but haven't put this into my code, as I have assumed you know how to do this already. Also in Activity 2 once you retrieve the username you will need to store it as a global variable, so that it can be used once the user finishes filling out the form on Activity 2.

Categories

Resources