My approach is using the Facebook login method (Facebook SDK for Android). The Facebook authentication process returns (on success) an object from which I can get the user's email then I save it in my Endpoints class using Datastore API. To check if user already logged in I chose the SharedPreferences approach with GSON library to parse objects into JSON String and save them in the prefs.
Links and my sample codes below :
Regarding the Authenticator I found this SO answer
More info about Facebook login method
Saving custom objects in SharedPreferences
Getting user's email through Facebook auth
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
if (isSessionCalled == false) {
Log.i(TAG, "Logged in...");
System.out.println("Token=" + session.getAccessToken());
new Request(
session,
"/me",
null,
HttpMethod.GET,
new Request.Callback() {
public void onCompleted(Response response) {
if (response != null) {
GraphObject object = response.getGraphObject();
String email = (String) object.getProperty("email");
Log.i(TAG, "user email : " + email);
String firstName = (String) object.getProperty("first_name");
String lastName = (String) object.getProperty("last_name");
mUserTask = new UserAsyncTask();
mUserTask.execute(email);
}
}
}
).executeAsync();
isSessionCalled = true;
}
else {
Log.w(TAG, "session called twice");
}
}
else if (state.isClosed()) {
Log.i(TAG, "Logged out...");
}
}
Storing the user in my backend :
@ApiMethod(name = "storeUserModel")
public UserModel storeUserModel(UserModel userModel) throws UserAlreadyExistsException, UserNotFoundException {
logger.info("inside storeUser");
String email = userModel.getEmail();
UserModel checkUser = getUserModel(email);
logger.info("after getUserModel with email " + email);
if (checkUser == null) {
logger.info("inside checkUser is NULL");
DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService();
Transaction txn = datastoreService.beginTransaction();
try {
Entity userEntity = new Entity(UserModel.class.getSimpleName(), email);
userEntity.setProperty("nickname", userModel.getNickname());
// TODO save the pheromones with the key of userEntity
datastoreService.put(userEntity);
txn.commit();
storePheromoneList(userModel.getPheromoneList(), userEntity.getKey(), datastoreService);
} finally {
if (txn.isActive()) {
logger.severe("rolled back with email : " + email);
txn.rollback();
}
}
}
else {
throw new UserAlreadyExistsException();
}
return userModel;
}
A class that triggers calls to my backend
public class EndpointsServer implements Server {
private static final String TAG = "EndpointsServer";
final UserModelApi userEndpointsApi;
public EndpointsServer() {
UserModelApi.Builder builder = new UserModelApi.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), null)
.setRootUrl("http://10.0.2.2:8080/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
@Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
});
userEndpointsApi = builder.build();
}
@Override
public User getUser(String email) {
User user = null;
try {
Log.d(TAG, "in getUser with email " +email);
// get user from db
UserModel userModel = userEndpointsApi.getUserModel(email).execute();
if (userModel != null) {
Log.d(TAG, "user != null with email " + email);
user = new User(userModel);
}
} catch (IOException e) {
e.printStackTrace();
}
return user;
}
}
Storing user on successful login :
String userString = gson.toJson(user, User.class);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(USER_KEY, userString);
editor.commit();
There's more to it like another client side class to build the api call to the backend and lots of other details. I can post it if you want.