androidpostgresqlkotlinandroid-studio

Login button needs to be clicked twice to login


I'm making an app on Android Studio and I need to verify credentials when they log in to the app. The app works with an API and to verify credentials I created this function in the database to check someones email and password: (postgresql)

create or replace function login (emailf text, passwordf text)
returns boolean
language plpgsql
as
$$
declare pp text;
begin
pp = (select pass_w from utilizador where utilizador.email = emailf);
if (pp = passwordf) then return true;
else return false;
end if; end
$$

I'm parsing the data through this CheckLoginas function:

var bola: Boolean? = null
fun CheckLoginas(c: Context?, email: String, pass: String): Boolean? {
        var mQueue: RequestQueue
        mQueue = Volley.newRequestQueue(c);
        var url = "https://myurl.com" + "/utilizador/login/" + email + "/" + pass
        val request = JsonArrayRequest(Request.Method.GET, url, null, Response.Listener {
                response ->try {
                var jsonArray = JSONArray()
                jsonArray = response.getJSONArray(0)
                for (i in 0 until jsonArray.length())
                {
                        val jsonObject : JSONObject? = jsonArray.getJSONObject(i)
                        //val user = jsonArray.getJSONObject(i)
                        //val bool = jsonObject.getBoolean("login")
                        val boo : Boolean = jsonObject!!.getBoolean("login")
                        println("im inside CheckLoginas boo $boo\n\n")
                        bola = boo
                }
        } catch (e: JSONException) {
                e.printStackTrace()
        }
        }, Response.ErrorListener { error -> error.printStackTrace() })
        mQueue?.add(request)
        return bola
}

bola variable is a global variable because I needed to return a boolean from the function so I can know if the credentials check (or not) in another activity.

The Problem:

To login when the credentials are correct, I have to press twice in the login button. If the email and password are correct, the first time I press it gives me the "Wrong credentials" error and in the second time it logs in. I already tried to do it with a while(), I checked it step by step and it seems fine, nothing seems to work to fix this error... The function works, the API too, and the app itself kinda of works too, it just has this bug of clicking twice on the button... This is the activity code:

package com.example.crowdzero

import CheckLoginas
import Database
import android.content.Intent
import android.os.Bundle
import android.view.View.OnFocusChangeListener
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.textfield.TextInputLayout
import java.lang.Thread.sleep

class Login : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        val log_in_btn_log_in = findViewById<Button>(R.id.log_in_btn_log_in)
        val log_in_btn_registar = findViewById<Button>(R.id.log_in_btn_registar)

        log_in_btn_log_in.setOnClickListener {
            verificacao()

        }

        log_in_btn_registar.setOnClickListener {
            val intent = Intent(this, Registo::class.java)
            startActivity(intent)
        }
    }



    private fun verificacao() {

        val log_in_input_text_email = findViewById<TextInputLayout>(R.id.log_in_input_text_email)
        val log_in_input_text_password = findViewById<TextInputLayout>(R.id.log_in_input_text_password)
        val string_email = log_in_input_text_email?.getEditText()?.getText().toString()?.trim()
        val string_password = log_in_input_text_password?.getEditText()?.getText().toString()?.trim()

            if (string_email.isNullOrEmpty())
            {
                log_in_input_text_email.setError(" ")
            }
            else if (string_password.isNullOrEmpty())
            {
                log_in_input_text_password.setError(" ")
            }
            else
            {
                   val email = log_in_input_text_email.editText?.text.toString()
                   val password = log_in_input_text_password.editText?.text.toString()
                   //var baca = CheckLoginas(this,email,password)
                   println(email)
                   println(password)
                   var baca: Boolean? = null
                   baca = CheckLoginas(this, email, password)
                   //baca = CheckLoginas(this,email,password)
                   if (baca == false) {
                       //Toast.makeText(this, "Esta conta não está registada", Toast.LENGTH_SHORT).show();
                       println("Im inside if in login baca $baca")
                   } else if (baca == true) {
                       Toast.makeText(this, email, Toast.LENGTH_SHORT).show();
                       Toast.makeText(this, password, Toast.LENGTH_SHORT).show();
                       val intent = Intent(this, Home::class.java)
                       startActivity(intent)
                       finish()
                   }
            }
    }
}

When I test this with an actual email and password from the database, baca variable stays false when it should be true, since CheckLoginas bool var is true. This is what is causing the problem.

image that shows it

I'm fairly new to the Database-API-App thing, so please forgive me if its a trivial thing


Solution

  • You are calling baca = CheckLoginas(this, email, password) baca will not update immedietly, the next line if (baca == false) will be executed before you API response arrives, so after you got some response baca becomes true. This is why you need to click twice.