The expired sms code immediately after receiving the sms - android

I have an application that you can log in to by phone number
After entering the phone number I receive an SMS code
A new screen opens where I can enter this code
When I enter the code, I get information that the code is expired
Sign: First screen
onSignIn() {
const {code, phoneNumber} = this.state;
const newNumber = '+' + code + phoneNumber;
if (newNumber.length > 10) {
firebase
.auth()
.signInWithPhoneNumber(newNumber)
.then(confirmResult => {
this.setState({result: confirmResult});
const navigateAction = NavigationActions.navigate({
routeName: 'SecurityCode',
params: {phoneAuthResponse: confirmResult},
});
this.props.navigation.dispatch(navigateAction);
})
.catch(error => {
if (error.message === 'TOO SHORT') {
alert('Please enter a valid phone number');
} else {
alert(error.message);
}
});
} else {
alert('Please Enter Your Number');
}
}
Confirm: Second screen
onConfirmCode() {
const {securityCode} = this.state;
if (securityCode.length > 5) {
this.props.navigation.state.params.phoneAuthResponse
.confirm(securityCode)
.then(async user => {
const ref = firebase.database().ref(`users/${user.uid}`);
ref.once('value', async snapshot => {
let data = snapshot.val();
if (!data) {
this.props.navigation.navigate('CreateProfile', {
user: {uid: user.uid, phone_number: user.phoneNumber},
});
} else {
this.props.reduxLoginUser(data);
this.props.navigation.navigate('InviteContacts');
}
});
})
.catch(error => console.warn(error.message));
} else {
alert('Please enter the 6 digit code');
}
}
What is done wrong?

Check if the user has been created (You can do this on the Firebase project page)
If it is created then there is another problem to be solved
You must catch that the user is created and go to the screen after logging in

Related

Firebase cloud function gets triggered twice. First time 'error', second time 'ok'

Just trying to impletment Stripe Payment into my Android App.
The trouble i have is that my cloud function is triggered twice when i enter a credit card in my app. the first trigger returns an "error" status and the second trigger returns an "ok" status
Here is the code i use to save the Stripe token to my firebase realtime database:
if (cardToSave != null) {
stripe.createToken(
cardToSave,
object:TokenCallback {
override fun onSuccess(token: Token?) {
val currentUser = FirebaseAuth.getInstance().currentUser?.uid
val database = FirebaseDatabase.getInstance()
val pushId = database.getReference("stripe_customers/$currentUser/sources/").push().key
val ref = database.getReference("stripe_customers/$currentUser/sources/$pushId/token/")
//save the token id from the "token" object we received from Stripe
ref.setValue(token?.id)
.addOnSuccessListener {
Log.d(TAG, "Added Stripe Token to database successfully")
}
.addOnFailureListener {
Log.d(TAG, "Failed to add Token to database")
}
}
...
Here is the cloud function i copied straight from Stripe's example in their github repo:
// Add a payment source (card) for a user by writing a stripe payment source token to Realtime database
exports.addPaymentSource = functions.database
.ref('/stripe_customers/{userId}/sources/{pushId}/token').onWrite((change, context) => {
const source = change.after.val();
if (source === null){
return null;
}
return admin.database().ref(`/stripe_customers/${context.params.userId}/customer_id`)
.once('value').then((snapshot) => {
return snapshot.val();
}).then((customer) => {
return stripe.customers.createSource(customer, {source});
}).then((response) => {
return change.after.ref.parent.set(response);
}, (error) => {
return change.after.ref.parent.child('error').set(userFacingMessage(error));
}).then(() => {
return reportError(error, {user: context.params.userId});
});
});
Any help would be appreciated!
EDIT:
index.js
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const logging = require('#google-cloud/logging');
//functions.config() is firebase's environment variables
const stripe = require('stripe')(functions.config().stripe.token);
const currency = functions.config().stripe.currency || 'USD';
// [START chargecustomer]
// Charge the Stripe customer whenever an amount is written to the Realtime database
exports.createStripeCharge = functions.database.ref('/stripe_customers/{userId}/charges/{id}')
.onCreate((snap, context) => {
const val = snap.val();
// Look up the Stripe customer id written in createStripeCustomer
return admin.database().ref(`/stripe_customers/${context.params.userId}/customer_id`)
.once('value').then((snapshot) => {
return snapshot.val();
}).then((customer) => {
// Create a charge using the pushId as the idempotency key
// protecting against double charges
const amount = val.amount;
const idempotencyKey = context.params.id;
const charge = {amount, currency, customer};
if (val.source !== null) {
charge.source = val.source;
}
return stripe.charges.create(charge, {idempotency_key: idempotencyKey});
}).then((response) => {
// If the result is successful, write it back to the database
return snap.ref.set(response);
}).catch((error) => {
// We want to capture errors and render them in a user-friendly way, while
// still logging an exception with StackDriver
return snap.ref.child('error').set(userFacingMessage(error));
}).then(() => {
return reportError(error, {user: context.params.userId});
});
});
// [END chargecustomer]]
// When a user is created, register them with Stripe
exports.createStripeCustomer = functions.auth.user().onCreate((user) => {
return stripe.customers.create({
email: user.email,
}).then((customer) => {
return admin.database().ref(`/stripe_customers/${user.uid}/customer_id`).set(customer.id);
});
});
// Add a payment source (card) for a user by writing a stripe payment source token to Realtime database
exports.addPaymentSource = functions.database
.ref('/stripe_customers/{userId}/sources/{pushId}/token').onWrite((change, context) => {
const source = change.after.val();
if (source === null){
return null;
}
return admin.database().ref(`/stripe_customers/${context.params.userId}/customer_id`)
.once('value').then((snapshot) => {
return snapshot.val();
}).then((customer) => {
return stripe.customers.createSource(customer, {source:source});
}).then((response) => {
return change.after.ref.parent.set(response);
}, (error) => {
return change.after.ref.parent.child('error').set(userFacingMessage(error));
}).then(() => {
return reportError(error, {user: context.params.userId});
});
});
// When a user deletes their account, clean up after them
exports.cleanupUser = functions.auth.user().onDelete((user) => {
return admin.database().ref(`/stripe_customers/${user.uid}`).once('value').then(
(snapshot) => {
return snapshot.val();
}).then((customer) => {
return stripe.customers.del(customer.customer_id);
}).then(() => {
return admin.database().ref(`/stripe_customers/${user.uid}`).remove();
});
});
// To keep on top of errors, we should raise a verbose error report with Stackdriver rather
// than simply relying on console.error. This will calculate users affected + send you email
// alerts, if you've opted into receiving them.
// [START reporterror]
function reportError(err, context = {}) {
// This is the name of the StackDriver log stream that will receive the log
// entry. This name can be any valid log stream name, but must contain "err"
// in order for the error to be picked up by StackDriver Error Reporting.
const logName = 'errors';
const log = logging.log(logName);
// https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/MonitoredResource
const metadata = {
resource: {
type: 'cloud_function',
labels: {function_name: process.env.FUNCTION_NAME},
},
};
// https://cloud.google.com/error-reporting/reference/rest/v1beta1/ErrorEvent
const errorEvent = {
message: err.stack,
serviceContext: {
service: process.env.FUNCTION_NAME,
resourceType: 'cloud_function',
},
context: context,
};
// Write the error log entry
return new Promise((resolve, reject) => {
log.write(log.entry(metadata, errorEvent), (error) => {
if (error) {
return reject(error);
}
return resolve();
});
});
}
// [END reporterror]
// Sanitize the error message for the user
function userFacingMessage(error) {
return error.type ? error.message : 'An error occurred, developers have been alerted';
}

Firebase phone number authentication, code is expired every time

I have added firebase authentication in my application. It works fine if i add phone number of other user in my phone. But if i add mine phone number it sends OTP but when i enter that OTP every time it shows error "SMS code has expired".
Is there any auto authentication? Is there something that i missing?
I have used below code to send OTP
firebase.auth().signInWithPhoneNumber(this.state.countryCode + this.state.phoneNumber)
.then(confirmResult => {
this.setState({
progressVisible: false
})
console.log("confirmResult is " + confirmResult)
AsyncStorage.setItem('CountryCode', this.state.countryCode);
AsyncStorage.setItem('PhoneNumber', this.state.phoneNumber);
this.props.navigation.navigate("OtpScreen", {
confirmResult, isConnected: this.state.isConnected
})
})
I have used below code to verify OTP
this.state.confirmResult.confirm(this.state.otpText)
.then(user => {
// this.setState({
// progressVisible: false
// })
console.log("Debug starts, 2");
this.hitAuthApi()
})
.catch(error => {
this.setState({
progressVisible: false
})
setTimeout(() => {
Alert.alert("Error" + error);
}, 100)
});
There is a firebase in-build listener for auto login, which need to initialise in component. It will automatically detect SMS in android.
this.unsubscribe = firebase.auth().onAuthStateChanged((user) => {
// alert(JSON.stringify(user))
if (user) {
//hit Api
} else {
// User has been signed out, reset the state
}
});

Android Studio Google+ login

I don't now why this code stops running, I've put some flags it has been senseless. It just goes to the end of the code, and does nothing. There you have some of the code.
loginGoogle(){
this.googlePlus.login({
'prompt':'consent',
'hd':'go-labs.net',
'webClientId': '660851996372-sou3k2to7661epk1a78mfid6hap105ne.apps.googleusercontent.com',
'offline': true
})
//the code just stop running here
.then(res =>{
if(res.email.endsWith('#go-labs.net')){
const googleCredential = firebase.auth.GoogleAuthProvider
.credential(res.idToken);
firebase.auth().signInWithCredential(googleCredential)
.then(response => {
this.dbUsers.addUser(response.uid, response.displayName, response.email);
this.loading.dismiss().then(() => {
this.navCtrl.setRoot(PulperiaPage);
});
});
}
else{
this.loading.dismiss().then(() => {
this.googlePlus.disconnect().then(res => {
this.presentAlert('That's not a valid account');
}).catch(error => {
});
});
}
//and then run this
}, err => {
this.loading.dismiss().then(() => {
this.presentAlert('Denied Access');
});
});
this.loading = this.loadingCtrl.create();
this.loading.present();
}

Fetch data from fbsdk react native

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);
}
);
}

I using cordova-plugin-ibeacon but not working(does'nt find beacons in android)

here is code
beacon-provider.ts >>
initialise(): any {
let promise = new Promise((resolve, reject) => {
if (this.platform.is('cordova')) {
IBeacon.enableBluetooth();
this.delegate = IBeacon.Delegate();
this.delegate.didRangeBeaconsInRegion()
.subscribe(
data => {
this.events.publish('didRangeBeaconsInRegion', data);
},
error => console.error()
);
this.region = IBeacon.BeaconRegion('deskBeacon', '24DDF411-8CF1-440C-87CD-E368DAF9C93E');
IBeacon.startRangingBeaconsInRegion(this.region)
.then(
() => {
resolve(true);
},
error => {
console.error('Failed to begin monitoring: ', error);
resolve(false);
}
);
} else {
console.error("This application needs to be running on a device");
resolve(false);
}
});
return promise;
}
}
home.ts >>
export class HomePage {
beacons: BeaconModel[] = [];
zone: any;
constructor(public navCtrl: NavController, public platform: Platform, public beaconProvider: BeaconProvider, public events: Events) {
this.zone = new NgZone({ enableLongStackTrace: false });
}
ionViewDidLoad() {
this.platform.ready().then(() => {
this.beaconProvider.initialise().then((isInitialised) => {
if (isInitialised) {
this.listenToBeaconEvents();
}
});
});
}
listenToBeaconEvents() {
this.events.subscribe('didRangeBeaconsInRegion', (data) => {
this.zone.run(() => {
this.beacons = [];
let beaconList = data.beacons;
beaconList.forEach((beacon) => {
let beaconObject = new BeaconModel(beacon);
this.beacons.push(beaconObject);
});
});
});
}
}
In this code, the result of alert(JSON.stringify(data)) is:
{"eventType":"didRangeBeaconslnRegion","region":{"identifier":"desk beacon","uuid":"24DDF411-8CF1-440C-87CD-E368DAF9C93E","typeName":"BeaconRegion"}, "beacons":[]}
The field data.beacons is empty.
What is the problem?
one more question i try BLE-central plugin first but,
when i was using BLE-central plugin i get signal but it was not given to me major , minor value if i get this value from advertising ?
There are lots of things that might cause this behavior:
Verify that Bluetooth is on
Verify that your app has been granted runtime location permissions needed to detect Bluetooth devices. Go to Settings -> Apps -> [Your app name] -> Permissions, and make sure you see a Location entry with the switch turned on.
Verify using an off-the-shelf detector app that your beacon actually is transmitting the identifier you expect. Try my Locate app here: https://play.google.com/store/apps/details?id=com.radiusnetworks.locate&hl=en

Categories

Resources