title: OkHttp: <-- HTTP FAILED: java.net.UnknownServiceException: CLEARTEXT communication to 10.0.2.2 not permitted by network security policy
body: <p>I have implemented <strong>google sign-in with Firebase authentication</strong> in my Android app succesfully. 
  <a href="https://i.stack.imgur.com/jEtQ3.png" rel="noreferrer"><img src="https://i.stack.imgur.com/jEtQ3.png" alt="enter image description here"></a></p>
  
  <p>As you see, I have logged-in with my account and it appears on the Firebase console.  </p>
  
  <p>The function <strong><em>firebaseAuthWithGoogle</em></strong> authenticates the user with Firebase after he logs-in with Google Sign-in:  </p>
  
  <pre><code>private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
      Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId());
  AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
  mFirebaseAuth.signInWithCredential(credential)
          .addOnCompleteListener(this, new OnCompleteListener&lt;AuthResult&gt;() {
              @Override
              public void onComplete(@NonNull Task&lt;AuthResult&gt; task) {
                  if (task.isSuccessful()) {
                      // Sign in success, update UI with the signed-in user's information
                      Log.d(TAG, "signInWithCredential:success");
                      final FirebaseUser user = mFirebaseAuth.getCurrentUser();
  
  
                      //This is to connect to the http server and save the user data in my MySql database
                      FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(LoginActivity.this, new OnSuccessListener&lt;InstanceIdResult&gt;() {
                          @Override
                          public void onSuccess(InstanceIdResult instanceIdResult) {
                              String userToken = instanceIdResult.getToken();
                              String uid = user.getUid();
                              String name = user.getDisplayName();
                              String email = user.getEmail();
                              String profileUrl = user.getPhotoUrl().toString();
                              String coverUrl = "";
                              UserInterface userInterface = ApiClient.getApiClient().create(UserInterface.class);
                              Call&lt;Integer&gt; call = userInterface.signin(new LoginActivity.UserInfo(uid,name,email,profileUrl,coverUrl,userToken));
  
                              call.enqueue(new Callback&lt;Integer&gt;() {
                                  @Override
                                  public void onResponse(Call&lt;Integer&gt; call, Response&lt;Integer&gt; response) {
                                      progressDialog.dismiss();
                                      Toast.makeText(LoginActivity.this,"Login succesfull AFTER API CALL",Toast.LENGTH_SHORT).show();
                                      startActivity(new Intent(LoginActivity.this,MainActivity.class));
                                      finish();
  
                                  }
  
                                  @Override
                                  public void onFailure(Call&lt;Integer&gt; call, Throwable t) {
                                      progressDialog.dismiss();
                                      Toast.makeText(LoginActivity.this,"Login failed AFTER API CALL",Toast.LENGTH_SHORT).show();
  
                                  }
                              });
                          }
                      });
                  } else {
                      // If sign in fails, display a message to the user.
  
  
                   Log.w(TAG, "signInWithCredential:failure", task.getException());
                      }
  
                      // ...
                  }
              });
  }
  </code></pre>
  
  <p>Another thing the function <strong><em>firebaseAuthWithGoogle</em></strong> does is: Connect to the http Apache server and save the user information in a <strong><em>MySQL users table</em></strong> through this code snippet: </p>
  
  <pre><code> //This is to connect to the http server and save the user data in my MySql database
                          FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(LoginActivity.this, new OnSuccessListener&lt;InstanceIdResult&gt;() {
                              @Override
                              public void onSuccess(InstanceIdResult instanceIdResult) {
                                  String userToken = instanceIdResult.getToken();
                                  String uid = user.getUid();
                                  String name = user.getDisplayName();
                                  String email = user.getEmail();
                                  String profileUrl = user.getPhotoUrl().toString();
                                  String coverUrl = "";
                                  UserInterface userInterface = ApiClient.getApiClient().create(UserInterface.class);
                                  Call&lt;Integer&gt; call = userInterface.signin(new LoginActivity.UserInfo(uid,name,email,profileUrl,coverUrl,userToken));
  
                                  call.enqueue(new Callback&lt;Integer&gt;() {
                                      @Override
                                      public void onResponse(Call&lt;Integer&gt; call, Response&lt;Integer&gt; response) {
                                          progressDialog.dismiss();
                                          Toast.makeText(LoginActivity.this,"Login succesfull AFTER API CALL",Toast.LENGTH_SHORT).show();
                                          startActivity(new Intent(LoginActivity.this,MainActivity.class));
                                          finish();
  
                                      }
  
                                      @Override
                                      public void onFailure(Call&lt;Integer&gt; call, Throwable t) {
                                          progressDialog.dismiss();
                                          Toast.makeText(LoginActivity.this,"Login failed AFTER API CALL",Toast.LENGTH_SHORT).show();
  
                                      }
                                  });
                              }
                          });
                      } 
  </code></pre>
  
  <p>So after the user has been <strong>succesfully authenticated</strong>, the call to the server fails and this line is obviously executed:  </p>
  
  <pre><code> Toast.makeText(LoginActivity.this,"Login failed AFTER API CALL",Toast.LENGTH_SHORT).show();  
  </code></pre>
  
  <p>I am using <strong>Retrofit</strong> as an <strong>http client</strong> along with <strong><em>okhttp</em></strong> as an <strong><em>http body interceptor</em></strong> to <strong><em>log the http requests</em></strong> as follows:  </p>
  
  <blockquote>
    <p>ApiClient.java</p>
  </blockquote>
  
  <pre><code>  public  static  Retrofit getApiClient(){
          HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);
          OkHttpClient httpClient = new OkHttpClient.Builder()
                  .addInterceptor(httpLoggingInterceptor)
                  .build();
  
          if(retrofit==null){
              retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
                      .client(httpClient)
                      .addConverterFactory(GsonConverterFactory.create())
                      .build();
  
          }
          return retrofit;
      }
  }
  </code></pre>
  
  <p>So after the Toast Text <strong><em>"Login failed AFTER API CALL"</em></strong> appears on the emulator, I have this on the log:  </p>
  
  <pre><code>D/OkHttp: --&gt; POST http://10.0.2.2/friendster/public/app/login
      Content-Type: application/json; charset=UTF-8
      Content-Length: 413
  D/OkHttp: {"CoverUrl":"","email":"MyEmail@gmail.com","name":"Ahmed Ghrib","profileUrl":"https://lh6.googleusercontent.com/-S8l_5gZaXJ8/AAAAAAI/AAAAAAAAAAA/ACHi3rfObo6-Ta-wxrMUvcAZ8Yg/s96-c/photo.jpg","uid":"YACACYYDcGVr26N8OHuTuQlQqvU2","userToken":"ecxdtFaKldI:APA91bHb1PAA5hU6i1oMqnSsDXXkAaXNb6dynyaYmhU_soHTWmLXud6REjCpqTjsGpgdBh1NMYUqAr3SaTUWapN4v73zkvyYD2f3yegUP3H38eeU_JtH7NOSMKbF4U"}
  D/OkHttp: --&gt; END POST (413-byte body)
  W/e.myapplicatio: Verification of okhttp3.internal.http.ExchangeCodec okhttp3.internal.connection.RealConnection.newCodec$okhttp(okhttp3.OkHttpClient, okhttp3.Interceptor$Chain) took 134.353ms
  D/OkHttp: &lt;-- HTTP FAILED: java.net.UnknownServiceException: CLEARTEXT communication to 10.0.2.2 not permitted by network security policy  
  </code></pre>
  
  <p>So I found-out that this is causing the error:   </p>
  
  <blockquote>
    <p>CLEARTEXT communication to 10.0.2.2 not permitted by network security
    policy</p>
  </blockquote>
  
  <p>After going through StackOverflow, I found-out that I needed to create this file:  </p>
  
  <blockquote>
    <p>src/main/res/xml/network_security_config.xml</p>
  </blockquote>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;network-security-config&gt;
      &lt;domain-config cleartextTrafficPermitted="true"&gt;
          &lt;domain includeSubdomains="true"&gt;api.example.com(to be adjusted)&lt;/domain&gt;
      &lt;/domain-config&gt;
  &lt;/network-security-config&gt; 
  </code></pre>
  
  <p>And adding this to the Manifest:      </p>
  
  <pre><code> &lt;application
       ---
          android:networkSecurityConfig="@xml/network_security_config"&gt;  
  </code></pre>
  
  <p>Having tested my database with Postman, I am sure the problem lies in my Android project.<br>
  I thought that this should've solved the issue. But, I still have the exact same issue.  I still get this error in the log:  </p>
  
  <blockquote>
    <p>CLEARTEXT communication to 10.0.2.2 not permitted by network security
    policy</p>
  </blockquote>