I have implemented firebase phone authentication mechanism to login user with following
code:
(<any>window).FirebasePlugin.verifyPhoneNumber('+91'+this.phone, 60, function (credential) {
//alert("sms sent successfully"+ credential.verificationId);
//this.verificationId = credential.verificationId;
let modal = this.modalCtrl.create(verificationPage,{verificationId: credential.verificationId});
modal.present();
}, error => {
alert(JSON.stringify(error));
console.log("error: " + error);
});
}
but credential.verificationId value can't able to store or send to another page
verify() {
this.signInCredential = firebase.auth.PhoneAuthProvider.credential(this.verificationId, this.code);
alert("u"+JSON.stringify(this.signInCredential));
firebase.auth().signInWithCredential(this.signInCredential).then((info) => { alert("check"+JSON.stringify(info));}, (error) => {
alert("err"+JSON.stringify(error));})
}
How to resolve above error?
You should get the parameters from the nav params, directly it won't work.
try
constructor(public params: Navparams){
}
verify() {
let verificationId = params.get("verificationId");
this.signInCredential =
firebase.auth.PhoneAuthProvider.credential(verificationId, this.code);
alert("u"+JSON.stringify(this.signInCredential));
firebase.auth().signInWithCredential(this.signInCredential).then((info) =>
{
alert("check"+JSON.stringify(info));}, (error) => {
alert("err"+JSON.stringify(error));
})
}
i hope this will help you.
For your reference check this article
https://medium.com/#gbrigens/ionic-3-phone-authentication-with-firebase-dbed967e95ef
Related
I am using react-native-fbsdk-next and followed all steps to set up Android/iOS (https://www.npmjs.com/package/react-native-fbsdk-next)
iOS works perfectly.
On android i receive the following redirect right after user clicks the LoginButton provided by the the fb sdk:
Here is my code:
<LoginButton
onLoginFinished={getOnLoginFinished()}
onLogoutFinished={() => {
console.log('logout.');
}}
/>
function getOnLoginFinished() {
return async (error, result) => {
let userAccessToken;
LoginManager.setLoginBehavior('native_with_fallback');
if (error) {
console.log('login has error: ' + result.error);
} else if (result.isCancelled) {
console.log('login is cancelled.');
} else {
AccessToken.getCurrentAccessToken()
.then(data => {
setUserAccessToken(data.accessToken.toString());
console.log(data.accessToken.toString());
console.log(result.grantedPermissions);
console.log(JSON.stringify(result));
})
.catch(err => {
console.log(`Get current access token, err ${err}`);
});
}
};
}
Expected deprecation, more detail here:
https://developers.facebook.com/docs/facebook-login/android/deprecating-webviews
Along with potential solution.
I ran into a bug whenever I run my React Native app on an Android device (physical and emulator). Yet, no problem at all on iOS. These functions are supposed to scan the database table for user handles and return an object if the handle already exists.
This is what the error looks like:
TypeError: Cannot read property 'handle' of null
at exports.handler (/var/task/index.js:7:36)
I'm using React Native, AWS Lambda, and EXPO.
This code lives within dbfunctions.js on the front end.
export async function scanHandles(){
return new Promise((resolve, reject) => {
let { auth } = store.getState()
let reqBody = {
userId: auth.user.username,
handle: auth.handle_update,
}
let path = '/u/scan-handle'
let myInit = {
headers: { 'Content-Type': 'application/json' },
body: reqBody,
}
console.log('myInit', myInit)
console.log('handle', auth.handle_update)
API.get(apiName, path, myInit)
.then((resp) => {
// if false, then handle does not exist
// if true, then handle already exists
resolve(resp)
})
.catch((error) => {
console.warn('Scan Handle', error)
reject(error)
})
})
}
Console logging auth.handle_update does print out the expected string. myInit also prints out the expected object.
On the back end, I'm using this for my scan:
const AWS = require("aws-sdk");
const docClient = new AWS.DynamoDB.DocumentClient({ region: "us-west-1" });
exports.handler = (event, context, callback) => {
let e = JSON.parse(event.body);
var params = {
TableName: event.stageVariables.user,
FilterExpression: "handle = :handle",
ExpressionAttributeValues: { ":handle": e.handle }
};
docClient.scan(params, function(err, data) {
if (err) {
console.log("ERROR:", err);
let response = {
statusCode: err.statusCode,
headers: {},
body: JSON.stringify(err)
};
callback(response);
}
if (data.Count >= 1) {
// if user name exists
// call back handle exists response
let handleExistsResponse = {
statusCode: 200,
body: JSON.stringify({ Success: true })
};
callback(null, handleExistsResponse);
} else {
let response = {
statusCode: 200,
body: JSON.stringify({ Success: false })
};
callback(null, response);
}
});
};
Any idea as to why this would work on iOS and not Android?
EDIT:
Upon further testing, let e = JSON.parse(event.body) is returning null. So I console logged event and got a big ol object. Within this object, I found body and it's still null. So the body object isn't being passed it properly. Still confused about it working on iOS and not Android.
Did it!
Okay so API.get doesn't like body's being passed in. Instead, it wants a query parameter. So the lambda params looks like:
var params = {
TableName: event.stageVariables.user,
FilterExpression: "handle = :handle",
ExpressionAttributeValues: {
":handle": event["queryStringParameters"]["handle"]
}
};
And the front end function is:
export async function scanHandles(){
return new Promise((resolve, reject) => {
let { auth } = store.getState()
let handle = auth.handle_update
let path = `/u/scan-handle?handle=${handle}`
let myInit = {
headers: { 'Content-Type': 'application/json' },
}
API.get(apiName, path, myInit)
.then((resp) => {
// if false, then handle does not exist
// if true, then handle already exists
resolve(resp)
})
.catch((error) => {
console.warn('Scan Handle', error)
reject(error)
})
})
}
Works on both iOS and Android. Wonder why it wasn't working before?
Hi I have implemented the Facebook login in my react native app. I have not used the standard button that comes with sdk. Everything work fine login is successful. But now I don't know how to extract data from Facebook user profile i.e name, email.
Below is my code
_fbAuth() {
LoginManager.logInWithReadPermissions(['public_profile']).then(function (result) {
if (result.isCancelled) {
console.log('Login was Cancelled');
} else {
const { navigate } = this.props.navigation;
//
console.log('Login Successful' + result.grantedPermissions.toString());
}
}, function (error) {
console.log('An error has occured' + error);
})
}
code for button
<TouchableHighlight onPress={() => { this._fbAuth() }}>
<Image source={require('../images/facebook-logo.png')} style={styles.facebook}></Image>
</TouchableHighlight>
You need to use AccessToken function along with the LoginManager to get the token when login is successful. After receiving the token, we can use this token to retrieve data of logged-in user using graph api of facebook.
Consider the code below:
import { LoginManager, AccessToken } from 'react-native-fbsdk';
async _fbAuth() {
let { isCancelled } = await LoginManager.logInWithReadPermissions(['public_profile','user_posts']);
if ( !isCancelled ) {
let data = await AccessToken.getCurrentAccessToken();
let token = data.accessToken.toString();
await afterLoginComplete(token);
}
else {
console.log('Login incomplete');
}
}
const afterLoginComplete = async (token) => {
const response = await fetch(
`https://graph.facebook.com/me?fields=id,name,first_name,last_name,gender,picture,cover&access_token=${token}`);
let result = await response.json();
// use this result as per the requirement
};
You can learn how to use facebook graph API from here
import {AccessToken,LoginManager} from 'react-native-fbsdk';
fbAuth() {
var current = this;
const { navigate } = this.props.navigation;
LoginManager.setLoginBehavior('web');
LoginManager.logInWithReadPermissions(['public_profile','email']).then(
function (result) {
if (result.isCancelled) {
console.log('Login was cancelled');
}
else {
//var accessToken = null;
AccessToken.getCurrentAccessToken().then(
(data) => {
console.log(data.accessToken.toString())
const{accessToken} = data
// with the help of access token you can get details for fb login
console.log('accessToken: ' + accessToken);
fetch('https://graph.facebook.com/v2.5/me?fields=email,name,friends&access_token=' +accessToken)
.then((response) => response.json())
.then((json) => {
console.log('jsonn: ' + json);
console.log('Login name: ' + json.name);
console.log('Login id: ' + json.id);
console.log('Login email: ' + json.email);
var nsn = json.name
console.log('Login email state: ' +nsn);
var idfb = json.id
console.log('Login email state: ' +idfb);
var idemail = json.email
console.log('Login email state: ' +idemail);
})
.catch(() => {
reject('ERROR GETTING DATA FROM FACEBOOK')
})
})
}
},
function (error) {
console.log('Login failed with error: ' + error);
}
);
}
Hello I tried to set the state on fetch call like this:
getCats() {
fetch(GLOBALS.API + '/specials.php?action=getCats&key=' + GLOBALS.KEY)
.then((response) => response.json())
.then((responseJson) => {
this.setState = ({
dataSource: "test"
});
Alert.alert("test");
})
.catch((error) => {
console.log(error.toString());
});
}
componentDidMount() {
this.getCats();
console.log(this.state.dataSource);
}
but the line:
console.log(this.state.dataSource);
return me undefined
and I get an alert of "test"
what the problem?
tnx a lot
You Can Make Use of callbacks.
Below is the code example
getCats(successCallBack, failureCallback) {
fetch(GLOBALS.API + '/specials.php?action=getCats&key=' + GLOBALS.KEY)
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
failureCallback();
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data)
successCallBack(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
failureCallback();
});
}
Below is the code for success and failure call backs
successCallBack(data) {
console.log(data)
}
failureCallback() {
alert("failure");
}
Below is the code to bind success and failure callbacks.
getCats(this.successCallBack.bind(this), this.failureCallback.bind(this));
Fetch is asynchronous so it will return immediately, before the code in the then clauses are run. Therefore, setState will not have run before the console logging.
This question already has an answer here:
Variable not updating with fetch response data in Angular 2 beta
(1 answer)
Closed 6 years ago.
I try to explain in English, but I don't speak it.
I'm working in a Ionic 2. I try to do a http request with post method and I am emulate in SDK Android emulator and I can see in the logcat:
Cannot call method 'post' of undefined at
file:///android_asset/www/build/js/app.bundle.js:2265
But I review and don't see anything, I rewrite my clientId and ClientSecret to can post here. I put a trace console.log(this.http) in the login function and this attribute is undefined, althought is inject in the class' constructor.
My code:
import {Page, Platform} from 'ionic-angular';
import {Http, Headers, HTTP_PROVIDERS} from 'angular2/http';
#Page({
templateUrl: 'build/pages/home/home.html',
providers: [ HTTP_PROVIDERS ]
})
export class HomePage {
static get parameters() {
return [[Platform],[Http]];
}
constructor(platform, http) {
this.platform = platform;
this.http = http;
this.clientId = "clientId";
this.clientSecret = "clientSecret";
}
login() {
this.platform.ready().then(() => {
this.googleLogin().then((success) => {
alert(success.access_token);
}, (error) => {
alert(error);
});
});
}
googleLogin() {
return new Promise(function(resolve, reject) {
var browserRef = window.cordova.InAppBrowser.open("https://accounts.google.com/o/oauth2/auth?client_id=" + "clientId" + "&redirect_uri=http://localhost/callback&scope=email%20profile&approval_prompt=force&response_type=code&access_type=offline", "_blank", "location=no,clearsessioncache=yes,clearcache=yes");
browserRef.addEventListener("loadstart", (event) => {
if ((event.url).indexOf("http://localhost/callback") === 0) {
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
var parameters = "client_id=" + "clientId" + "&client_secret=" + "clientSecret" + "&redirect_uri=http://localhost/callback" + "&grant_type=authorization_code" + "&code=" + requestToken
var requestToken = (event.url).split("code=")[1];
this.http.post("https://accounts.google.com/o/oauth2/token", parameters, { header:headers })
.subscribe( data => { resolve(data); },
error => { reject("Problem authenticating with Google"); }
);
browserRef.removeEventListener("exit", (event) => {});
browserRef.close();
}
});
browserRef.addEventListener("exit", function(event) {
reject("The Google sign in flow was canceled");
});
});
}
}
The code tries to authenticate with Google OAuth2, althought the error seems to be in the attributes in the constructor(http, clientId, clientSecret) there are not defined when the login function is called. I don't know what's wrong!
It might have something to do with the scoping of 'this', depending on what calls the googleLogin function.
Try using an arrow function:
googleLogin = () => {
...
}
It's because you don't use an arrow function when defining your promise. So the this keyword doesn't correspond to the instance of the component itself. With arrow functions, you can use the lexical this that will correspond to the component instance.
googleLogin() {
return new Promise((resolve, reject) => {
(...)
});
}
instead of
googleLogin() {
return new Promise(function(resolve, reject) {
(...)
});
}
See this link for more hints about the lexical this of arrow functions:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions.