Creando nuestro sistema de login y registro (III)

Estas últimas dos semanas vimos como crear las pantallas para nuestro registro y login y como autenticar y registrar a nuestros usuarios en un servidor. Esta semana nos vamos a centrar en el trabajo en el cliente, en nuestro dispositivo Android.


Durante este artículo iremos desempolvando algunos de los artículos que ya escribimos ya que algunas cosas como el acceso a base de datos no lo volveremos a explicar para que no se haga muy pesado. Vamos a crear la clase Usuario que es donde haremos el proceso más importante en la parte Android.

public class Usuario {
 
 private String Name = "";
 private String Email = "";
 private String UID = "";
 
    private static String KEY_SUCCESS = "success";
    private static String KEY_UID = "uid";
    private static String KEY_NAME = "name";
    private static String KEY_EMAIL = "email";
    private static String KEY_CREATED_AT = "created_at";
    private static String KEY_USER = "user";

 private static String loginURL = "URL DEL SERVIDOR/index.php";
    private static String registerURL = "URL DEL SERVIDOR/index.php";
 
 private static String login_tag = "login";
    private static String register_tag = "register";
    
    private Activity activity;
 

    public void login(Activity activity, String email, String password){
     this.activity = activity;
     HttpClientManager httpclient = new HttpClientManager(activity);
     httpclient.addNameValue("tag", login_tag);
     httpclient.addNameValue("email", email);
     httpclient.addNameValue("password", password);
     
     httpclient.setOnExecuteHttpPostAsyncListener(new OnExecuteHttpPostAsyncListener() {
   @Override
   public void onExecuteHttpPostAsyncListener(String ResponseBody) {
    try {     
     JSONObject json = new JSONObject(ResponseBody);
     if (json.getString(KEY_SUCCESS) != null) {
      if((Integer.parseInt(json.getString(KEY_SUCCESS)) == 1)){     
       if(Usuario.this.saveLogin(Usuario.this.activity, json))
        ListenerLoginUsuario.onLoginCorrect(json, "Login correcto");
       else
        ListenerLoginUsuario.onLoginWrong("Login incorrecto");       
      } else {
       ListenerLoginUsuario.onLoginWrong("Login incorrecto");       
      }
     } else{
      ListenerLoginUsuario.onLoginWrong("Login incorrecto");      
     }     
    } catch (JSONException e) {
     ListenerLoginUsuario.onLoginWrong("Login incorrecto");     
    }
   }

   @Override
   public void onErrorHttpPostAsyncListener(String message) {
   }   
  });
     
     httpclient.executeHttpPost(loginURL);
    } 
    

 public void register(Activity activity, String username, String email, String password){
  this.activity = activity;
  HttpClientManager httpclient = new HttpClientManager(activity);
  httpclient.addNameValue("tag", register_tag);
  httpclient.addNameValue("name", username);
  httpclient.addNameValue("email", email);
  httpclient.addNameValue("password", password);
  
  httpclient.setOnExecuteHttpPostAsyncListener(new OnExecuteHttpPostAsyncListener() {
   @Override
   public void onExecuteHttpPostAsyncListener(String ResponseBody) {
    try {
     JSONObject json = new JSONObject(ResponseBody);     
     if (json.getString(KEY_SUCCESS) != null) {
      if((Integer.parseInt(json.getString(KEY_SUCCESS)) == 1)){
       if(Usuario.this.saveLogin(Usuario.this.activity, json))
        ListenerRegisterUsuario.onRegisterFinish(json, "Registro correcto");
        else
        ListenerRegisterUsuario.onRegisterFail("Estás registrado pero no puedes loguearte ahora");       
      }else
       ListenerRegisterUsuario.onRegisterFail("Error durante el registro");
     } else {
      ListenerRegisterUsuario.onRegisterFail("Error durante el registro");
     }
    } catch (JSONException e) {
     ListenerRegisterUsuario.onRegisterException(e, "Error durante el registro");
    }
   }

   @Override
   public void onErrorHttpPostAsyncListener(String message) {
   }
  });  
  httpclient.executeHttpPost(registerURL);  
 }
 
 private boolean saveLogin(Activity activity, JSONObject json){
  boolean save = false;
  this.logout(activity);
  try {
   JSONObject user = json.getJSONObject(KEY_USER);
   DBLogin dblogin = new DBLogin(activity);
   dblogin.addUser(user.getString(KEY_NAME), user.getString(KEY_EMAIL), json.getString(KEY_UID), user.getString(KEY_CREATED_AT));
   dblogin.close();
   save = true;   
  } catch (JSONException e) {}    
  return save;
 }
 

 public void logout(Activity activity){
  DBLogin dblogin = new DBLogin(activity);
  dblogin.resetTables();
  dblogin.close();
 } 
 

    public boolean isUserLoggedIn(Activity activity){
        DBLogin db = new DBLogin(activity);
        int count = db.getRowCount();
        db.close();
        if(count > 0){
            // user logged in
            return true;
        }
        return false;
    }
    
    public void readUser(Activity activity){
     DBLogin dblogin = new DBLogin(activity);
     Cursor cursor = dblogin.getCursorUsuario();
     if(cursor.moveToNext()){
      this.setName(cursor.getString(0));
      this.setEmail(cursor.getString(1));
      this.setUID(cursor.getString(2));
     }
     cursor.close();
     dblogin.close();
     
    }
 
 public interface OnRegisterUsuario{
  void onRegisterFinish(JSONObject json, String msg);
  void onRegisterException(Exception e, String msg);
  void onRegisterFail(String msg);
 } 
 private OnRegisterUsuario ListenerRegisterUsuario; 
 public void setOnRegisterUsuario(OnRegisterUsuario l){ListenerRegisterUsuario = l;}
 
 public interface OnLoginUsuario{
  void onLoginCorrect(JSONObject json, String msg);
  void onLoginWrong(String msg);
 }
 private OnLoginUsuario ListenerLoginUsuario;
 public void setOnLoginUsuario(OnLoginUsuario l){ListenerLoginUsuario = l;}

 public String getName() {return Name;}
 public void setName(String name) {Name = name;}
 public String getEmail() {return Email;}
 public void setEmail(String email) {Email = email;}
 public String getUID() {return UID;}
 public void setUID(String uID) {UID = uID;}
 
}

Lo primero que hacemos es crear algunas de las variables que necesitaremos entre ellas las que tienen la url del servicio que creamos la semana pasada. Vosotros ahí debéis sustituir por vuestra propia URL.

A continuación se crean dos variables con las palabras login y register seteadas, esto es para enviar a nuestro servidor y que evalue que proceso le estamos pidiendo que realice.

Vamos con el método Login. Si os fijais hacemos uso de la clase httpClientManager que ya explicamos hace un tiempo en el artículo como enviar datos a un servidor. Simplemente le pasamos como parámetros nuestro email, password y el tag para que el servicio sepa que estamos haciendo un login.

Nuestro servicio siempre nos devolverá un json como respuesta el cual debemos evaluar. Lo primero de todo es buscar el parámetro success y verificar su estado. Si todo fue bien guardaremos la última vez que se hizo login correctamente en base de datos y quien es el usuario logado.

Para el login se ha creado un Listener que nos lanzará un evento cuando el login finalice correctamente, cuando el login falle o cuando se produzca una excepción y se envía un mensaje personalizado para saber que ha fallado exactamente.

El proceso de registro sigue prácticamente la misma lógica, únicamente le estamos pasando a mayores el nombre de usuario para que se guarde en el servidor.

El siguiente método saveLogin, accede a la base de datos de nuestro dispositivo mediante la clase DBLogin que ahora veremos y guarda al usuario actual que le pasamos mediante un json. Antes de eso hace un logout de cualquier posible usuario que podamos tener almacenado.

El método logout simplemente eliminará la información almacenada de un usuario en la base de datos del dispositivo. isUserLoggedIn nos servirá para comprobar en nuestra aplicación si ya hay un usuario registrado, readUser simplemente leera los datos del usuario que ya está almacenado en nuestro dispositivo.

La siguiente clase que debéis crear es DBLogin y servirá para acceder a los datos almacenados de nuestro usuario. Esta clase debe heredar de bbdd que la creamos hace tiempo en el artículo como guardar datos en base de datos. En la clase bbdd debeis incluir en el onCreate la creación de la tabla de usuarios ya que deben crearse todas las tablas de la aplicación al mismo tiempo. La estructura de la tabla sería así:

private String SQLCreateLogin = "CREATE TABLE login("
                + " id INTEGER PRIMARY KEY,"
                + " name TEXT,"
                + " email TEXT UNIQUE,"
                + " uid TEXT,"
                + " created_at TEXT" + ")";

Y en el onCreate ejecutais:

@Override
 public void onCreate(SQLiteDatabase db) {
  db.execSQL(SQLCreateLogin);  
 }

Vamos con la clase DBLogin ahora:

public class DBLogin extends bbdd {

 public static String Table = "login";
 
    private static final String KEY_ID = "id";
    private static final String KEY_NAME = "name";
    private static final String KEY_EMAIL = "email";
    private static final String KEY_UID = "uid";
    private static final String KEY_CREATED_AT = "created_at";
 
 public DBLogin(Context context) {
  super(context);  
 }
 

    public void addUser(String name, String email, String uid, String created_at) {
        SQLiteDatabase db = this.getWritableDatabase();
 
        ContentValues values = new ContentValues();
        values.put(KEY_NAME, name);
        values.put(KEY_EMAIL, email);
        values.put(KEY_UID, uid); 
        values.put(KEY_CREATED_AT, created_at); 
 
        
        db.insert(Table, null, values);
        db.close();
    }
 
    /**
     * Obtener usuario de la base de datos
     * */
    public HashMap<String, String> getUserDetails(){
        HashMap<String,String> user = new HashMap<String,String>();
        String selectQuery = "SELECT  * FROM " + Table;
 
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        cursor.moveToFirst();
        if(cursor.getCount() > 0){
            user.put("name", cursor.getString(1));
            user.put("email", cursor.getString(2));
            user.put("uid", cursor.getString(3));
            user.put("created_at", cursor.getString(4));
        }
        cursor.close();
        db.close();

        return user;
    }
 
  
    public int getRowCount() {
        String countQuery = "SELECT  * FROM " + Table;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);
        int rowCount = cursor.getCount();
        db.close();
        cursor.close(); 
       
        return rowCount;
    }
    
    public Cursor getCursorUsuario(){
     SQLiteDatabase db = getReadableDatabase();
  
  return db.rawQuery("SELECT name, email, uid " +
    " FROM "+Table 
    
    , null); 
    }
 
  
    public void resetTables(){
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(Table, null, null);
        db.close();
    }

}

Lo que queda aquí son instrucciones SQL muy fáciles, addUser insertará el usuario logueado en la base de datos del dispositivo, getUserDetails nos devolverá los datos del usuario, getRowCount cuenta el número de filas que hay en la tabla login, de esta forma sabemos si hay alguien conectado, getCursorUsuario lee los datos del usuario y resetTables elimina los datos del usuario previamente almacenado en esta tabla.

Usuario usuario = new Usuario();
      if(usuario.isUserLoggedIn(this))
         usuario.readUser(this);
       else 
         navegarALogin();

Lo último que queda por ver es lo que debemos hacer cuando nos encontramos en una página que requiere login. El proceso es muy sencillo, en el onCreate de la Activity creamos un nuevo usuario, comprobamos si está logueado, si lo está y lo necesitáis lo leéis y en caso de no estar logueado debéis implementar un método que os lleve a la pantalla de login.

Comments are closed.