0

I am just trying to show user data after hitting the API using Retrofit. my api response is:

{ 
   "password":"111222333",
   "name":"test name",
   "email":"testem@gmail.com",
   "username":"test1",
   "customer_id":"201060",
   "phone":"0196789"
}

but unfortunately, I am getting

"Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $" error.

I am totally stuck to show my json response.

My User.java class:


    public class User {
      @SerializedName("name")
      @Expose
      private String name;
      @SerializedName("email")
      @Expose
      private String email;
      @SerializedName("username")
      @Expose
      private String username;
      @SerializedName("customer_id")
      @Expose
      private String customerId;
      @SerializedName("phone")
      @Expose
      private String phone;
      @SerializedName("password")
      @Expose
      private String password;
      public String getName() {
        return name;
      }
      public String getEmail() {
        return email;
      }
      public String getUsername() {
        return username;
      }
      public String getCustomerId() {
        return customerId;
      }
      public String getPhone() {
        return phone;
      }
      public String getPassword() {
        return password;
      }
    }

My Login class:


    Gson gson = new GsonBuilder().setLenient().create();
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("https://us-central1-gmx-notification.cloudfunctions.net/")
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .build();
            all_api = retrofit.create(allApi.class);
    private void getUserDetails(String userName,String passWord){
            Call<User> call = all_api.getUserDetails(userName,passWord);
            call.enqueue(new Callback<User>() {
                @Override
                public void onResponse(Call<User> call, Response<User> response) {
                    if(!response.isSuccessful()){
                        Log.d(response.body());
                    }
                    else{
                        User user = response.body();
                        String content = "";
                        content+= "Name: "+user.getName()+"\n";
                        content+= "Email: "+user.getEmail()+"\n";
                        content+= "Customer ID: "+user.getCustomerId()+"\n";
                        content+= "Phone: "+user.getPhone()+"\n";
                        Log.d(content);
                  }
    });
    }

and my retrofit api class:


    package com.material.components;
    import java.util.List;
    import retrofit2.Call;
    import retrofit2.http.GET;
    import retrofit2.http.Query;
    public interface allApi {
      @GET("login")
      Call <User> getUserDetails(
              @Query("email") String email,
              @Query("password") String password
      );
    }

halfer
  • 19,824
  • 17
  • 99
  • 186
Enayet Hossain
  • 187
  • 1
  • 4
  • 14
  • This might help you [expected-begin-object-but-was-string-at-line-1-column-1](https://stackoverflow.com/questions/28418662/expected-begin-object-but-was-string-at-line-1-column-1) – AgentP Nov 01 '19 at 11:13
  • 1
    Can you please attach a screenshot from Postman where we can see model that come from backend? Because from you error I see that your model doesn't feet to response however your model looks good. I guess your response somethink like this { data { 'usermode' } } – Eugene Troyanskii Nov 01 '19 at 11:22
  • Kindly post complete repsonse string that you are getting after hitting api – Shadow Droid Nov 01 '19 at 11:28
  • If you have no Postman you could add Interceptor to your OkHttpClient to see what your backend side send to you. – Eugene Troyanskii Nov 01 '19 at 11:33

1 Answers1

2

When i hit you api https://us-central1-gmx-notification.cloudfunctions.net/login?email=qwery@gmail.com&password=12345678

I got this response

Error: could not handle the request

So as your error says you expected Object but got a string. So or an error on the backend side or the request is incorrect or you forgot to add something to the request(Header or something else...).

For sure problem not in your model just got not a model that you expect in the response. Add Interceptor in your OkHttpClient to see what you get to be sure.

You need add this dependency to gradle

implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1'

And here is a code example your API that will printing all networking stuff in the log:

public class NetworkManager {

    private static RESTAuthService restAuthService;

    /*timeout values in seconds*/
    private static final int CONNECTION_TIMEOUT = 10;
    private static final int WRITE_TIMEOUT = 10;
    private static final int READ_TIMEOUT = 10;

    static RESTAuthService getRESTAuthService() {
        if (restAuthService == null) {
            synchronized (NetworkManager.class) {
                if (restAuthService == null) {

                    OkHttpClient client = new OkHttpClient.Builder()
                            .addInterceptor(new RESTInterceptor())
                            .connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
                            .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
                            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
                            .build();

                    Retrofit retrofit = new Retrofit.Builder()
                            .baseUrl(NetworkConfig.BASE_AUTH_URL)
                            .addConverterFactory(GsonConverterFactory.create())
                            .client(client)
                            .build();

                    restAuthService = retrofit.create(RESTAuthService.class);
                }
            }
        }
        return restAuthService;
    }

    private static class RESTInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            Buffer buffer = new Buffer();
            if (request.body() != null) {
                request.body().writeTo(buffer);
            }
            Log.d("HTTP Request", "Request to " + request.url().toString()
                    + "\n" + request.headers().toString()
                    + "\n" + buffer.readUtf8());
            long t1 = System.nanoTime();
            Response response = chain.proceed(request);
            long t2 = System.nanoTime();

            String msg = response.body().string();
            msg = msg.replace("\r", ""); // Note: Messages with '\r' not displayed correctly in logcat

            Log.d("HTTP Response", String.format("Response from %s in %.1fms%n\n%s",
                    response.request().url().toString(), (t2 - t1) / 1e6d, msg));

            Log.d("HTTP Response", "Response code = " + response.code());

            return response.newBuilder()
                    .body(ResponseBody.create(response.body().contentType(), msg))
                    .build();
        }
    }
    }

Your MyLogin class will be something like this:

public class MuLogin {
/*timeout values in seconds*/
    private static final int CONNECTION_TIMEOUT = 10;
    private static final int WRITE_TIMEOUT = 10;
    private static final int READ_TIMEOUT = 10;

    allApi = all_api;

    OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(new RESTInterceptor())
        .connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
        .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
        .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
        .build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://us-central1-gmx-notification.cloudfunctions.net/")
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();

    all_api =retrofit.create(allApi.class);

    public void getUserDetails(String userName, String passWord) {
        Call<User> call = all_api.getUserDetails(userName, passWord);
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                if (!response.isSuccessful()) {
                    Log.d(response.body());
                } else {
                    User user = response.body();
                    String content = "";
                    content += "Name: " + user.getName() + "\n";
                    content += "Email: " + user.getEmail() + "\n";
                    content += "Customer ID: " + user.getCustomerId() + "\n";
                    content += "Phone: " + user.getPhone() + "\n";
                    Log.d(content);
                }
            });
        }
    }
    private static class RESTInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            Buffer buffer = new Buffer();
            if (request.body() != null) {
                request.body().writeTo(buffer);
            }
            Log.d("HTTP Request", "Request to " + request.url().toString()
                    + "\n" + request.headers().toString()
                    + "\n" + buffer.readUtf8());
            long t1 = System.nanoTime();
            Response response = chain.proceed(request);
            long t2 = System.nanoTime();

            String msg = response.body().string();
            msg = msg.replace("\r", ""); // Note: Messages with '\r' not displayed correctly in logcat

            Log.d("HTTP Response", String.format("Response from %s in %.1fms%n\n%s",
                    response.request().url().toString(), (t2 - t1) / 1e6d, msg));

            Log.d("HTTP Response", "Response code = " + response.code());

            return response.newBuilder()
                    .body(ResponseBody.create(response.body().contentType(), msg))
                    .build();
        }
    }
}
  • hi Eugene Troyanskii, thanks for your reply. actually where should i write this RESTAuthService ... is it in my Login class above or in the retrofit api class? However, try to hit https://us-central1-gmx-notification.cloudfunctions.net/login?email=zahidneru@gmail.com&password=111222333 – Enayet Hossain Nov 01 '19 at 12:58
  • @EnayetHossain my RESTAuthService it is your api interface. Add RESTInterceptor as inner class in your "My Login class" and then create your retrofit as represented in my example. – Eugene Troyanskii Nov 01 '19 at 13:13
  • thanks... actually my input text was not correctly passed to the API. now it's working – Enayet Hossain Nov 01 '19 at 17:16