Expo Google Authentication doesn't work on production - expo

I implemented Expo Authentication on my app, following the code from the doc https://docs.expo.io/guides/authentication/#google.
On local with the Expo client its working fine, in the IOS simulator and also in the web browser but when I build the app (expo build android) and try on my Android phone, the Google popup comes, I put my id and it send me back to the login page but NOTHING happen.
I put some alert to understand what was going on but I dont even get any, useEffect doesn't fire, responseGoogle doesnt seem to change.
const [requestGoogle, responseGoogle, promptAsyncGoogle] =
Google.useAuthRequest({
expoClientId:
"my_id",
androidClientId:
"my_id,
webClientId:
"my_id",
});
useEffect(() => {
alert("useEffect fired (Google)");
if (responseGoogle?.type === "success") {
const { authentication } = responseGoogle;
// success
alert("success : "+JSON.stringify(responseGoogle));
// some code to check and log the user...
} else {
alert('no success : '+JSON.stringify(responseGoogle));
}
}, [responseGoogle]);
Any idea ?

Apparently its a know bug so here is not the answer but an alternative with expo-google-sign-in :
import * as GoogleSignIn from "expo-google-sign-in";
async function loginWithGoogle() {
try {
await GoogleSignIn.askForPlayServicesAsync();
const { type, user } = await GoogleSignIn.signInAsync();
if (type === "success") {
alert(JSON.stringify(user));
}
} catch ({ message }) {
toast.show("Erreur:" + message);
alert("login: Error:" + message);
}
}

Related

my smart contract is not responding and error saying web3 is not defined

[error saying web3 is not defined][1]<script>
var myContract;
async function CheckMetamaskConnection() {
// Modern dapp browsers...
if (window.ethereum) {
window.web3 = new Web3(window.ethereum);
try {
// Request account access if needed
await ethereum.enable();
// Acccounts now exposed
return true;
} catch (error) {
// User denied account access...
return false;
}
}
// Legacy dapp browsers...
else if (window.web3) {
window.web3 = new Web3(web3.currentProvider);
// Acccounts always exposed
return true;
}
// Non-dapp browsers...
else {
console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');
return false;
}
}
$(document).ready(async function () {
var IsMetamask = await CheckMetamaskConnection();
if (IsMetamask) {
myContract = await web3.eth.contract(SmartContractABI).at(SmartContractAddress);
getCandidate(1);
getCandidate(2);
await myContract.eventVote({
fromBlock:0
}, function(err, event){
console.log("event :", event);
getCandidate(event.args._candidateid.toNumber());
});
console.log("myContract :", myContract);
console.log("Metamask detected!")
} else {
console.log("Metamask not detected");
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Metamask not detected!',
onClose() {
location.reload();
}
});
}
});
async function getCandidate(cad){
await myContract.candidates(cad, function(err, result){
if (!err) {
console.log("result : ", result);
document.getElementById("cad" + cad).innerHTML = result[1];
document.getElementById("cad"+cad+'count').innerHTML = result[2].toNumber();
}
});
}
async function Vote(cad){
await myContract.vote(cad, function(err, result){
if(!err){
console.log("We are winning!");
} else{
console.log("Can not connect to the smart contract");
}
})
}
</script>`
i have node.js and metamask in my system(windows 10)
i cloned you project from github and runned it by following command
npm install
node index.js
the UI deployed perfectly in localhost:3000 but when i try to vote the transaction is not working!!!
then i saw content on smart contract is not rendering!!!
then i checked metamask , which was connected and have 1 ether on ropsten network!!!
then i try ganache (local blockchain provider) and still the transaction is not working!!!
then i paste the smart contract in remix and get the ABI and smart contract address and still not working!!!
then i goto developer tool of browser and saw below error!!!!...i have no idea of this error!!!!...how can i solve this???
The error can be happening because the loading of Web3. Please, try this function:
async loadWeb3(){
if(window.ethereum){
window.web3 = new Web3(window.ethereum)
await window.ethereum.request({ method: 'eth_requestAccounts' })
}
else if(window.web3){
window.web3 = new Web3(window.ethereum)
}
else{
window.alert("Non-Ethereum browser detected. You should consider trying MetaMask!")
}
}
Also, do not forget to add the import on your javascript class:
import Web3 from 'web3'
and install the import with the npm:
npm i web3 --save

Angular HttpClient get request - how to get the text data sent?

I have an Angular/Ionic app that communicates with a Django backend. I am using this.http.get() to communicate with this server (on Heroku) and the Django server should be sending the text "OK". Instead, I am either (dependent on specific usage of this.http.get()) getting an error where the statusText is the text I want, or something like Object { _isScalar: false, source: {…}, operator: {…} }
My Django code is simple:
def make(request, otherParams):
...
return HttpResponse("OK")
I know that the get() has made it to the server, because the server runs certain things when the corresponding function is called.
How do I, from the Angular frontend, detect if the Django script has sent the "OK" or not?
(The error is not due to any of various CORS policies, I have installed django-cors-headers)
EDIT:
if it's relevant, I'm on a Windows PC, testing on localhost/Firefox Nightly with Ionic 5 and Angular 9.
Here is my frontend code, cutting the irrelevant bits. The way I've made my GET request is not consistent, having tried many. This one is suggested in the below post, and still fails.
import { Component, OnInit } from '#angular/core';
import { AlertController } from '#ionic/angular';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-submit',
templateUrl: './submit.page.html',
styleUrls: ['./submit.page.scss'],
})
export class SubmitPage implements OnInit {
constructor(public alertController: AlertController, private http: HttpClient) { }
ngOnInit() {
}
//irrelevant variable-getting
save() {
console.log(this.list);
if (this.title == null || this.title == "") {
this.presentAlert("Uncompleted fields", "Please complete the Title field!");
}
else if (this.sub == null || this.sub == "") {
this.presentAlert("Uncompleted fields", "Please complete the Subtitle field!");
}
else if (this.content == null || this.content == "") {
this.presentAlert("Uncompleted fields", "Please complete the Content field!");
} else {
try {
if (this.list.length == 0) {
console.log(this.list);
throw "empty list";
}
//more irrelevance
}
catch{ this.presentAlert("Uncompleted fields", "Please complete the list!"); }
if (temp2) {
this.makePost();
}
}
}
makePost() {
var temp = (<root url> + encodeURIComponent(this.title) + `/` + (this.posterID).toString() + '/' + encodeURIComponent(this.sub) + '/' + encodeURIComponent(this.content) + '/' + this.happy.toString() + '/' + this.angry.toString() + `/` + this.stressy.toString() + `/` + this.energy.toString() + '/' + this.worry.toString());
console.log(temp);
this.http.get(temp).toPromise()
.then(r => console.log('response', r)).catch(error => console.error(error));
}
}
Assuming you are using the HttpClient to invoke your GET request, you need to actually do something with this.http.get().
Try doing something like this instead:
If you can use async/await
const response = await this.http.get(<url>);
If you cannot use async/await
this.http.get(<url>).then(r => console.log('response', r) ).catch( error => console.error(error) );
If you just do:
const response = this.http.get(<url>);
console.log(response);
You are effectively logging the Promise and not the resolved Promise that holds the data you're after.
If you can show more code from your Angular app, it would help determine if this is your problem or not. For basic troubleshooting, I would first validate that your GET request (in your Python app) works by itself. Using Postman, you can test this (along with methods). If you GET request works fine, then the issue is more than likely something in you angular app which I described how to fix above.
It turned out that my Angular script was trying to interpret the response as JSON, not the plaintext I wanted. Using the code from the answer by mwilson and adding { responseType: 'text' } into the get() parameters, the console now logs the response successfully.
My The code snippet now looks like this: this.http.get(url, { responseType:'text'}).toPromise().then(r => console.log(r)).catch(error => console.error(error));
BTW feel free to point out any improvements/optimizations to the above code if you feel it needs it.

AWS Amplify, how to check if user is logged in?

I've been using the aws-amplify library with ionic and was wondering how I would check if a user is logged in? I'm coming from a firebase background so this is quite different. This is so that I can grant access to certain pages based on the user's log in status. In my auth provider I import Amplify {Auth}. I can see that it's possible to get several pieces of data but I'm not sure what to use. There's currentUserPoolUser, getCurrentUser(), getSyncedUser(), currentAuthenticatedUser, currentSession, getCurrentUser(), userSession, currentUserCredentials, currentCredentials and currentUserInfo. I can't seem to find any documentation on any of this either. Everything I've read and watched covers up until the user signs in... Is this all supposed to be done on the client? Thanks.
I'm using the ionViewCanEnter() function in every page to allow/deny access. The return value of this function determines if the page can be loaded or not (and it is executed before running the costructor). Inside this function you have to implement you logic.
In my case, using Amplify, I'm doing this:
async function ionViewCanEnter() {
try {
await Auth.currentAuthenticatedUser();
return true;
} catch {
return false;
}
}
Since amplify currentAuthenticatedUser() return a promise I use async await to wait for the response to know if the user is logged in or not.
Hey I think for now you can only use Auth.currentUserInfo(); to detect whether logged in or not. It will return undefined if you are not logged in or an object if you are.
This can be achieved using the fetchAuthSession() method of Auth.
final CognitoAuthSession res = await Amplify.Auth.fetchAuthSession();
if (res.isSignedIn) {
// do your thang
}
if you are using angular with ionic then you can do somthing like this in your authenticator service
import {AmplifyService} from 'aws-amplify-angular';
...
constructor(private amplifyService:AmplifyService)
{
this.amplifyService.authStateChange$.subscribe(auth => {
switch (auth.state) {
case 'signedIn':
this.signedIn = true;
case 'signedOut':
this.signedIn = false;
break;
default:
this.signedIn = false;
}
}
}
then you can use this.signedIn in your router with canActivate guard.
Angular router guard: https://angular.io/guide/router#preventing-unauthorized-access
You can make it a custom hook by listening to the hub (ionViewCanEnter from the above answers is for bootup of the app):
Hook tsx:
import {useState, useEffect} from 'react';
import {Hub, Auth} from 'aws-amplify';
export default function AuthenticatedStatus(): Boolean {
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
async function ionViewCanEnter() {
console.log('hey');
try {
const authenticatedUser = await Auth.currentAuthenticatedUser();
if (authenticatedUser !== undefined) {
setIsAuthenticated(true);
} else {
setIsAuthenticated(false);
}
} catch {
setIsAuthenticated(false);
}
}
useEffect(() => {
ionViewCanEnter();
});
useEffect(() => {
const listener = data => {
switch (data.payload.event) {
case 'signIn' || 'autoSignIn' || 'tokenRefresh':
console.log('is authenticated');
setIsAuthenticated(true);
break;
case 'signOut' || 'signIn_failure' || 'tokenRefresh_failure' || 'autoSignIn_failure':
console.log('is not authenticated');
setIsAuthenticated(false);
break;
}
};
Hub.listen('auth', listener);
});
return isAuthenticated;
}
how to use:
const isAuthenticated = AuthenticatedStatus();
An example that's worked with me, careful for flow control, both
event-loop style and async/await style:
import { Auth } from "aws-amplify";
...
exampleIsLoggedIn() {
const notLoggedInStringThrown = "The user is not authenticated";
Auth.currentAuthenticatedUser().then(
// eslint-disable-next-line #typescript-eslint/no-unused-vars
(_currentAuthenticatedUser) => {
this.$log.debug("Yes, user is logged in.");
},
(error) => {
if (error === notLoggedInStringThrown) {
this.$log.debug("No, user is not yet logged in.");
} else {
this.$log.error(error);
}
}
);
},
async exampleIsLoggedInAsync() {
const notLoggedInStringThrown = "The user is not authenticated";
try {
/* currentAuthenticatedUser = */ await Auth.currentAuthenticatedUser();
this.$log.debug("Yes, user is logged in.");
} catch (error) {
if (error === notLoggedInStringThrown) {
this.$log.debug("No, user is not yet logged in.");
} else {
this.$log.error(error);
}
}
},
import { Auth } from 'aws-amplify';
Auth.currentAuthenticatedUser({
// Optional, By default is false. If set to true,
// this call will send a request to Cognito to get the latest user data
bypassCache: false
})
.then((user) => console.log(user))
.catch((err) => console.log(err));
This method can be used to check if a user is logged in when the page is loaded. It will throw an error if there is no user logged in. This method should be called after the Auth module is configured or the user is logged in. To ensure that you can listen on the auth events configured or signIn.
Source: https://docs.amplify.aws/lib/auth/manageusers/q/platform/js/#retrieve-current-authenticated-user

NodeJS / iOS - How to get a returned value from a binary after calling it with HTTP POST

I have an iOS app (Objective C) and this app call some C++ binaries using NodeJs.
So far, I have been able to execute remotely my C++ program from a clicked button on my app using HTTP POST with the library AFNetworking 3.
iOS App --> Button clicked --> HTTP POST --> Node JS call --> C++ program call (this latter return true or false)
Now, I would like to get the value (True or False) returned by my program. How can I do that ?
I have already used the GET method to get a file on my server but I don't know if it's appropriate to use it for this case i.e get the returned result of my program.
Do you have an idea how can I achieve this ?
Thank
To be able to retrieve the value returned by your C++ program, you need first to retrieve the returned result from NodeJS.
Assuming you are using ExpressJS as your HTTP server, you should implement your endpoint with something like:
var execFile = require('child_process').execFile;
var express = require('express');
var app = express();
app.post('/endpoint', function (req, res) {
const child = execFile('my_exe', (error, stdout, stderr) => {
if (error) {
res.status(500).send('False')
} else {
if (stdout === 'True') {
res.status(200).send('True')
} else {
res.status(500).send('False')
}
}
});
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
If the call succeeded, the server will respond True with the status 200 and if it fails, it will return Falsewith a status False.
Now, in your call to the server from the iOS application, you can use Alamofire like:
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:#"POST" URLString:#"someURL" parameters:#{} error:nil];
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
/* Network error*/
NSLog(#"Error: %#", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
switch (httpResponse.statusCode) {
case 200:
NSLog(#"Success")
/* Code in case of success == Server returned True */
default:
/* Code in case of no success == Server returned False */
NSLog(#"Error");
}
}
}];
[dataTask resume];

How can i connect facebook and update status

I have examined Facebook Modul on this link
I would like to post message to facebook but I don't connect facebook with below code on Android and iOS simulator too.
var fb = require('facebook');
fb.appid = "55xxxxxxxxxx";
fb.permissions = ['publish_stream'];
// Permissions your app needs
fb.authorize();
fb.requestWithGraphPath('me/feed', {message: "Trying out FB Graph API and it's fun!"},
"POST", function(e) {
if (e.success) {
alert("Success! From FB: " + e.result);
} else {
if (e.error) {
alert(e.error);
} else {
alert("Unkown result");
}
}
});
I have just created an app on Facebook's http://developer.facebook.com page
Should i use Add Platform button on Facebook Developer setting tab?
If answer is yes. How can i fill
Facebook Plaform's iOS Bundle ID iPhone Store ID iPad Store ID
Facebook Plaform's Android Package Name Class Name Key Hashes
My app is not published on market. It is test case yet.
My Titanium SDK is 3.2.3GA and i am testing it on iOS 7.1 simulator
Thank you in advance.
Try to set an event listener to facebook login event like this :
var fb = require('facebook');
fb.appid = "55xxxxxxxxxx";
fb.permissions = ['publish_stream'];
// Permissions your app needs
fb.authorize();
fb.addEventListener("login", function(e) {
if (e.success) {
fb.requestWithGraphPath('me/feed', {
message : "Trying out FB Graph API and it's fun!"
}, "POST", function(e) {
if (e.success) {
alert("Success! From FB: " + e.result);
} else {
if (e.error) {
alert(e.error);
} else {
alert("Unkown result");
}
}
});
} else {
if (e.error) {
alert(e.error);
} else {
alert("Unkown result");
}
}
});