Ludiras
Ludiras

Reputation: 514

Pass parameters with Retrofit with Field

I'm following a retrofit course in which I create a small backend with an api in which I have a POST method to perform a teacher's login. In the course what he does is create a teacher and with the set method he passes him the email and the password, which is what this method receives in the API.

I would like to do it in such a way that in the call to Retrofit you pass directly this email and password and I have done it in the following way:

public class LoginActivity extends AppCompatActivity {

    private EditText etPasswordLogin, etEmailLogin;
    private Button btLogin;
    private TextView tvSignUp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        setupView();
    }

    private void setupView() {

        etPasswordLogin = findViewById(R.id.loginEditTextPassword);
        etEmailLogin = findViewById(R.id.loginEditTextEmail);
        btLogin = findViewById(R.id.buttonSignUp);
        tvSignUp = findViewById(R.id.textViewSignUp);

        btLogin.setOnClickListener(v -> userSignUp());
        tvSignUp.setOnClickListener(v -> startActivity(new Intent(getApplicationContext(), SignUpActivity.class)));
    }

    private void userSignUp() {

        String email = etEmailLogin.getText().toString().trim();
        String password = etPasswordLogin.getText().toString().trim();

        if (email.isEmpty()) {

            etEmailLogin.setError(getResources().getString(R.string.email_error));
            etEmailLogin.requestFocus();
            return;
        }

        if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {

            etEmailLogin.setError(getResources().getString(R.string.email_doesnt_match));
            etEmailLogin.requestFocus();
            return;
        }

        if (password.isEmpty()) {

            etPasswordLogin.setError(getResources().getString(R.string.password_error));
            etPasswordLogin.requestFocus();
            return;
        }

        if (password.length() < 4) {

            etPasswordLogin.setError(getResources().getString(R.string.password_error_less_than));
            etPasswordLogin.requestFocus();
            return;
        }

        login(email, password);
    }

    private void login(String email, String password) {

        String BASE_URL = "http://10.0.2.2:8040";

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        WebServiceApi api = retrofit.create(WebServiceApi.class);
        Call<List<Profesor>> call = api.login(email, password);

        call.enqueue(new Callback<List<Profesor>>() {
            @Override
            public void onResponse(Call<List<Profesor>> call, Response<List<Profesor>> response) {
                if (response.code() == 200) {
                    Log.d("TAG1", "Profesor logeado");
                } else if (response.code() == 404) {
                    Log.d("TAG1", "Profesor no existe");
                } else {
                    Log.d("TAG1", "Error desconocido");
                }
            }

            @Override
            public void onFailure(Call<List<Profesor>> call, Throwable t) {
                Log.d("TAG Error: ", Objects.requireNonNull(t.getMessage()));
            }
        });

    }
}

And this would be my model teacher:

public class Profesor {

    @SerializedName("id")
    private Long id;
    @SerializedName("nombre")
    private String nombre;
    @SerializedName("email")
    private String email;
    @SerializedName("password")
    private String password;
    @SerializedName("foto")
    private String photo;

    public Profesor(){}

    public Profesor(Long id, String nombre, String email, String photo) {
        this.id = id;
        this.nombre = nombre;
        this.email = email;
        this.photo = photo;
    }

    public Profesor(String email, String password){
        this.email = email;
        this.password = password;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPhoto() {
        return photo;
    }

    public void setPhoto(String photo) {
        this.photo = photo;
    }
}

Finally the call to Retrofit that I make is the following:

@FormUrlEncoded
@POST("api/login")
Call<List<Profesor>> login(@Field("email") String email, @Field("password") String password);

However when I run the application and pass through the form the email and password, in the log I return "Error desconocido", however in postman gives me answer without problems:

postman image

Any idea what I'm doing wrong?

Upvotes: 0

Views: 840

Answers (1)

Aram
Aram

Reputation: 695

Your postman request is not a form-urlencoded, but raw. You need to send a json as a request, and not a field. So to fix this, you may change your API, to handle form-urlencoded requests, or change the Android code this way.

public class LoginCredentials {
    @SerializedName("email")
    private String email;
    @SerializedName("password")
    private String password;

    public LoginCredentials(String email, String password) {
        this.email = email;
        this.password = password;
    }
}

and change this

@FormUrlEncoded
@POST("api/login")
Call<List<Profesor>> login(@Field("email") String email, @Field("password") String password);

to this

@POST("api/login")
Call<List<Profesor>> login(@Body LoginCredentials credentials);

Hope this will help.

Upvotes: 1

Related Questions