Search code examples
androidreactjsionic-frameworkionic-react

How to use community HTTP plugin in a Ionic React app when running the app on Android Emulator?


I’m working on an Ionic React App running on top of Capacitor. It works fine with axios requests in browser, but on Android I have CORS issues, that’s why I’m using the community HTTP plugin:https://github.com/capacitor-community/http

Example: I click on my Login button. My data such as email and password are supposed to be sent via HTTP post, but it catches the error I have put there: Try again’ .

Do you have any idea why it might happen?

No error logs regarding the request on Android Studio either. Only these:

    /system_process E/ClipboardService: Denying clipboard access to com.google.android.googlequicksearchbox, application is not in focus nor is it a system service for user 0
    E/netmgr: qemu_pipe_open_ns:62: Could not connect to the ‘pipe:qemud:network’ service: Invalid argument
    E/netmgr: Failed to open QEMU pipe ‘qemud:network’: Invalid argument
    E/wifi_forwarder: qemu_pipe_open_ns:62: Could not connect to the ‘pipe:qemud:wififorward’ service: Invalid argument
    E/wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe

To solve these errors I have added this setting inside application element:

    android:usesCleartextTraffic=“true”

but the errors still occur.

Android emulator is connected to Internet.

<!-- Permissions -->
    <uses-permission android:name="android.permission.INTERNET" />
 <!-- Network API -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Login.tsx:

import React from "react";
import { useHistory } from "react-router-dom";
import { useState, useContext } from "react";
import MyContext from "../my-context";
import {
  IonPage,
  IonHeader,
  IonContent,
  IonButton,
  IonInput,
  IonLabel,
  IonItem,
  IonGrid,
  IonCol,
  IonAlert,
} from "@ionic/react";
import { Http, HttpResponse } from "@capacitor-community/http";

const Login = () => {
  const history = useHistory();
  const {
    email,
    setEmail,
    password, 
    setPassword
  } = useContext(MyContext);

     const doLogin = async (e: any) => {
    e.preventDefault();

    const loginData = {
      email: email,
      password: password,
    };

    //https://github.com/capacitor-community/http
    const options = {
      url: "https://xx/login,
      data: loginData,
    };
    const response: HttpResponse = await Http.post(options)

      .then((response) => {

        if (response.data.token) {
          history.push("/home");
          window.location.reload();
        }
        return response.data;
      })
      .catch((error) => {
        setMessage(
          "Try again!"
        );
      setIserror(true);
      });
    };

return (
    <IonPage>
      <IonContent className="ion-padding ion-text-center">
        <IonGrid>
          <IonRow>
            <IonCol>
              <IonAlert
                isOpen={iserror}
                onDidDismiss={() => setIserror(false)}
                header={"Info!"}
                message={message}
                buttons={["Ok"]}
              />
            </IonCol>
          </IonRow>
         
                <h1>Login</h1>
              </IonCardTitle>
          
              <IonItem>
                <IonLabel position="floating">Email</IonLabel>
                <IonInput
                  name="email"
                  type="email"
                  value={email}
                  onIonChange={(e) => setEmail(e.detail.value!)}
                />
              </IonItem>

              <IonItem>
                <IonLabel position="floating">Password</IonLabel>
                <IonInput
                  name="password"
                  type="password"
                  value={password}
                  onIonChange={(e) => setPassword(e.detail.value!)}
                />
              </IonItem>
             
              <IonButton onClick={doLogin}>Login</IonButton>
             
        </IonGrid>
      </IonContent>
    </IonPage>
  );
};

export default Login;

I’m stuck with this issue since 3 days, so any help would be really, really appreciated. Thank you!


Solution

  • For anyone interested, I found the solution. In this doc https://github.com/capacitor-community/http, configuration for Android is missing.

    1- So, import and add http plugin in android\app\src\main\java\\MainActivity.java

    package com.myapp.com;
    
    import android.os.Bundle;
    
    import com.getcapacitor.BridgeActivity;
    import com.getcapacitor.Plugin;
    
    import java.util.ArrayList;
    import com.getcapacitor.plugin.http.Http; //added
    
    public class MainActivity extends BridgeActivity {
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        // Initializes the Bridge
        this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{
          // Additional plugins you've installed go here
          // Ex: add(TotallyAwesomePlugin.class);
          add(Http.class); //added
        }});
      }
    }
    

    2- Sync gradle files in Android Studio:

    File --> Sync Project with Gradle Files
    

    I wrote the request according to my needs and now it works perfectly.