How to connect the React Native app with Loopback API Explorer? - android

I have created a React Native app which can connect my own API but if I want to connect to the Loopback API, it always got some problem with the authentication, may I know how to connect the React Native app with the Loopback API? Previously, this is my own API:
var API_URL = 'http://192.168.10.130:8000/api';
exports.SIGNIN_URL = `${API_URL}/auth/token/`;
exports.TODOS_URL = (token) => `${API_URL}/workrequests/`;
But after I change to the Loopback API it cannot get the token from it so I also want to know how to get the access token from it and act it as an authentication token, thank you.
var API_URL = 'http://localhost:3000/api';
exports.SIGNIN_URL = `${API_URL}/Users/login/`;
exports.TODOS_URL = (token) => `${API_URL}/WorkRequests/`;
//AuthAction.js
import axios from 'axios';
import Keychain from 'react-native-keychain';
import {SIGNIN_URL} from '../api';
import {addAlert} from './alertsActions';
exports.loginUser = (username, password) => {
return function(dispatch) {
return axios.post(SIGNIN_URL, {username, password}).then((response) => {
var {token} = response.data;
console.log(token);
Keychain.setGenericPassword(username, token)
.then(function() {
dispatch(addAlert(token));
dispatch(authUser(token));
}).catch((error) => {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
});
}).catch((error) => {
dispatch(addAlert("Could not sign in."));
});
}
}
authUser = (token) => {
return {
type: 'AUTH_USER',
token
}
}
exports.unauthUser = {
type: 'UNAUTH_USER'
}

Related

Expo google sign in redirect always on app login on Standelone app

I hope you are doing well.
I have a problem when I connect with google on the emulator with android.
If I go through Expo Go on either Android or Ios, it works fine. But when I build my apk, and I install it on the emulator it sends me back to the same login page without redirecting me to the application.
Do you have an idea of the origin of the problem?
My google login function :
try {
const result = await promptAsync();
if (result.type === "success") {
/* `accessToken` is now valid and can be used to get data from the Google API with HTTP requests */
const { id_token } = result.params;
const provider = new firebase.auth.GoogleAuthProvider();
const credential =
firebase.auth.GoogleAuthProvider.credential(id_token);
auth.signInWithCredential(credential)
.then((res) => {
const user = res.additionalUserInfo.profile;
let action = addUserOnFirestore(
res.user?.uid,
user.email,
user.given_name,
user.family_name,
user.picture,
res
);
setIsLoading(true);
try {
dispatch(action);
} catch (err) {
setError(err.message);
}
setIsLoading(false);
})
.catch((error) => {
console.log("firebase cred err:", error);
});
} else {
console.log("cancelled");
}
} catch (e) {
console.log("general error : ", e);
return { error: true };
}
}
And the properties define :
const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
clientId: "XXXX",
iosClientId: "XXX",
androidClientId: "XXX",
androidStandaloneAppClientId: "XXX",
redirectUri: Platform.select({
// iOS handles redirectUri perfectly fine on it's own
ios: undefined,
// Due to Expo's bug, we need to manually encode the redirectUri
// https://github.com/expo/expo/issues/12044
android: makeRedirectUri({
// intent filter set up in app.config.js
// must be the same as "package name" in Google Cloud Console
native: 'packagename://oauthredirect',
}),
})
});
Thanks in advance for your responses.

React Native Android websocket connection erroring with 401 Unauthorized

I am trying to set up a simple websocket connection in my React Native app. It is returning the following error in Android: {"isTrusted": false, "message": "Expected HTTP 101 response but was '401 Unauthorized'"}. The websocket is opening fine in iOS, and using a websocket connection that does not require my user to be authenticated works (my user is authenticated for this server but it still say I'm not authorized).
Here is the relevant code in my app:
useEffect(() => {
const ws = new WebSocket(`wss://${DOMAIN}/api/stream/all`)
ws.onopen = () => {
console.log('websocket open') // --> iOS
}
ws.onerror = e => {
console.log('error', e) // --> Android
}
}, [])
Changing it to this works on Android:
useEffect(() => {
const ws = new WebSocket(`wss://echo.websocket.events/.ws`)
ws.onopen = () => {
console.log('websocket open') // --> Android & iOS
}
ws.onerror = e => {
console.log('error', e)
}
}, [])
Any idea why authentication is not working? Is there some Android config that needs to be changed so the authentication that already happened for this domain on https gets to the websocket connection somehow?
I ended up changing it to this (added session cookie to headers for Android):
if (Platform.OS === 'ios') {
const ws = new WebSocket(`wss://${DOMAIN}/api/stream/all`)
ws.onopen = () => {
console.log('websocket open') // --> it works!
}
} else {
const ws = new WebSocket(`wss://${DOMAIN}/api/stream/all`, '', { headers: {Cookie: sessionCookie } })
ws.onopen = () => {
console.log('websocket open') // --> it works!
}
}
I got the session cookie from the response after the user logged in and kept that in state to be used in the websocket connection: const sessionCookie = res.headers.get('set-cookie'). This solution may not work for everyone if login doesn't work the same way for you, but it may help someone.

After logging in with Google it doesn't redirect me back to my app on Android

I got an Ionic + Angular + Capacitor app with Angular Fire Auth for the Google login. My app logs me in with Google on the Web version of it, but when I export it to an Android device the Google login doesn't redirects me back to the App it just stays in the phone browser.
Any help will be appreciated.
Here's the method for the Google login:
async loginClickGoogle() {
try {
const user = await this.authService.loginGoogle();
//If the user exists
console.log('User loginclickgoogle ->', user);
if (user) {
const isVerified = this.authService.isEmailVerified(user);
if (isVerified) {
this.router.navigateByUrl('home');
this.authService.getUID();
} else {
this.emailNotVerifiedToast();
}
} else {
this.wrongUserLoginToast();
}
} catch (error) {
console.log('Error', error);
this.wrongUserLoginToast();
}
}
Here's the service method for the Google login:
async loginGoogle(): Promise<User> {
try {
const {user} = await this.afAuth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
this.userUID = user.uid;
return user;
}catch (error){
console.log('Error-->',error);
}
}
When using an android device you have to use GooglePlus plugin.
Docs here : https://ionicframework.com/docs/native/google-plus
import { GooglePlus } from '#awesome-cordova-plugins/google-plus/ngx';
constructor(private googlePlus: GooglePlus) { }
...
this.googlePlus.login({})
.then(res => console.log(res))
.catch(err => console.error(err));

Connecting to cloud function running on emulator from android emulator in react native

I am building an application and using firebase for the backend. I used react-native-firebase to use firebase in my application. I have developed a login cloud function
exports.login = functions.https.onCall((data, context) => {
console.log("data", data);
console.log("context", context);
return "Login successful";
});
On running npm run serve in the functions folder I am getting these configurations in my console.
Console output after running npm run serve inside functions folder for firebase
Also I have added the following code to connect to the cloud function from my android emulator running the application.
import functions from "#react-native-firebase/functions"
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const handleLogin = () => {
// console.log(email, password);
functions()
.useFunctionsEmulator("URL")
.httpsCallable("login")({ email, password })
.then((response) => {
alert(response);
});
}
for URL I have tried "http://localhost:5001/" as it is the port on which the functions emulator is listening
Port on which cloud functions is listening. But on running the application I am getting this error
Error on clicking login button in app console. I tried searching for the error but nothing relevant comes up. Any help will be appreciated.
These are my cloud functions that I have defined
exports.helloWorld = functions.https.onRequest((request, response) => {
functions.logger.info("Hello logs!", { structuredData: true });
response.send("Hello from Firebase!");
});
exports.signup = functions.https.onRequest((request, response) => {
console.log("request", request);
response.send("SignUp successfull");
});
exports.login = functions.https.onCall((data, context) => {
console.log("data", data);
console.log("context", context);
return "SignIn successfull";
});
I was able to work it out finally
const handleLogin = async () => {
functions().useFunctionsEmulator("http://localhost:5001")
const response = await functions().httpsCallable("login")({ email, password });
console.log("response", response);
}
This is all the code required to successfully call cloud function locally inside an emulator from your running android emulator.

FeathersJS login error when building for Android

I am building an Android app using Ionic. And using the following feathers_client.js
const feathers = require('#feathersjs/feathers');
const socketio = require('#feathersjs/socketio-client');
const auth = require('#feathersjs/authentication-client');
const io = require('socket.io-client');
const socket = io('http://mydomain.example:3030');
const feathers_client = feathers();
feathers_client
.configure(socketio(socket))
.configure(auth({ storage: window.localStorage }));
module.exports = feathers_client;
When I run the app at the browser it works fine. But when I run it at an Android device I only get "NotAuthenticated".
I am assuming this is happening because FeathersJS stores the JWT token at window.localStorage and this is not available at the Android app userspace.
Two questions:
1) Is there any way to tell FeathersJS to store this token somewhere else?
2) If not, anyone faced this situation and may provide me a solution?
By the way, this is my code for authenticating:
export class SSHSettingsPage implements OnInit {
public inputEmail: string;
public inputPassword: string;
constructor() { }
ngOnInit() {
}
public performLogin($event) {
let authObj: object = { "strategy": "local", "email": this.inputEmail, "password": this.inputPassword};
client.authenticate(authObj)
.then(res => {
console.log(res);
window.localStorage.setItem("user",JSON.stringify(res.user));
window.location.href = "/download";
})
.catch(err => {
console.log(err);
window.location.href = "/login-error";
})
}
}
As mentioned in the configuration API the storage option can be passed an instance of the React Native AsyncStorage:
import {AsyncStorage} from 'react-native';
// Available options are listed in the "Options" section
app.configure(auth({
storage: AsyncStorage
}))

Categories

Resources