Expo - React Native: Firebase Phone Number Authentication is failing - reactjs

I need help. I am trying to send a verification code with phone number authentication in EXPO and It works well in development. But I don't know why the same code is not working in production. I am getting this error,
verifyphonenumber failed: second argument “applicationVerifier” must be an implementation of firebase.auth.ApplicationVerifier
The FirebaseRecaptchaVerifierModal is not showing up when I click to send the verification code. I think, it is failing in the second argument of verifyPhoneNumber() but I can’t see how I can correct this.recaptchaVerifier.current using the Doc. Here is my code
import React, {Component} from 'react';
import { View, TextInput, TouchableOpacity } from 'react-native';
import firebase from 'firebase';
import config from '../../firebase.config';
import { FirebaseRecaptchaVerifierModal } from 'expo-firebase-recaptcha';
import {ToastError, ToastSuccess} from '../../utils/Toast';
import styles from './styles';
class PhoneAuthScreen extends Component {
constructor(props) {
super(props);
this.state = {
phoneNumber: '',
},
this.recaptchaVerifier = React.createRef();
}
onChangeText(key, value) {
this.setState({
[key]: value
})
}
signInWithPhoneNumber = async () => {
const { phoneNumber } = this.state;
const phoneProvider = new firebase.auth.PhoneAuthProvider();
try {
const verificationId = await phoneProvider.verifyPhoneNumber(
phoneNumber, this.recaptchaVerifier.current);
this.setState({ verificationId: verificationId });
ToastSuccess('Verification code has been sent to your phone.');
} catch (err) {
ToastError(err.message);
}
}
render() {
return (
<View style={styles.verifyPage}>
<View>
<View style={styles.telSection}>
<TextInput
style={styles.telInput}
placeholder='+1 201-555-0123'
placeholderTextColor='#080040'
keyboardType={'phone-pad'}
returnKeyType='done'
autoCapitalize='none'
autoCorrect={false}
secureTextEntry={false}
ref='PhoneInput'
autoCompleteType="tel"
value={this.state.phoneNumber}
onChangeText={(val) => {
this.onChangeText('phoneNumber', val)
}
}
/>
</View>
</View>
<FirebaseRecaptchaVerifierModal
ref={this.recaptchaVerifier}
firebaseConfig={config}
/>
<TouchableOpacity style={styles.confirmBtn} onPress={this.signInWithPhoneNumber}>
<Text style={styles.confirmText}>Send Verification Code</Text>
</TouchableOpacity>
</View>
)
};
}
export default PhoneAuthScreen;

Related

React Native jest testing: "Cannot read properties of undefined"

I am struggling to get my jest test going.
My Component:
//Login.js
import Dialog from "react-native-dialog";
import { View, TextInput } from "react-native";
export default class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
};
}
render() {
return (
<View>
<View>
<TextInput
testID="email"
value={this.state.email}
onChangeText={(text) => this.setState({ email: text })}
/>
</View>
<View>
<TextInput
testID="password"
value={this.state.password}
onChangeText={(text) => this.setState({ password: text })}
/>
</View>
<View>
<Dialog.Container>
<Dialog.Button label="hi" />
</Dialog.Container>
</View>
</View>
);
}
}
My Test file
//Login.test.js
import React from "react";
import { render, fireEvent } from "react-native-testing-library";
import Login from "./Login";
const mockedModule_dialog = jest.mock("react-native-dialog");
module.exports = mockedModule_dialog;
jest.mock("react-native-dialog", () => mockedModule_dialog);
describe("Login", () => {
describe("change text login", () => {
it("change text username and password", () => {
const { getByTestId } = render(<Login />);
// use fireEvent change value TextInput
fireEvent.changeText(getByTestId("email"), "admin");
fireEvent.changeText(getByTestId("password"), "admin#123");
// use toEqual check value TextInput
expect(getByTestId("email").props.value).toEqual("admin");
expect(getByTestId("password").props.value).toEqual(
"admin#123"
);
});
});
});
But every time I run yarn test, I am getting the following error Cannot read properties of undefined (Reading 'Container')
When I remove the <Dialog.Container> .... </Dialog.Container> then test passed.
What am I doing wrong? Mocking the library react-native-dialog is not done correctly?

Firebase | Reading data from Firebase returns "undefined", but console.log shows precise result

EDIT: I'm new to Stack, but why was my earlier thread locked? It just said "similar thread is found somewhere else" and the thread wasn't at all similar.
I am currently trying to update my own little personal weight tracker using Firebase and React Native. However, whenever I log DataSnapshot.val() I receive the input 22, which is perfect. But when I return the very same value I receive Undefined.
I tried both get() and onValue() with the same results. The path is correct, since I get the correct data using console.log.
https://firebase.google.com/docs/database/web/read-and-write?authuser=2
I tried following the above documentation. But is it updated? snapshot is currently DataSnapshot?
Firebase:
const readWeight = (database, userId) => {
get(ref(database, `users/${userId}/weight`)).then((DataSnapshot) => {
try {
if (DataSnapshot.exists()) {
console.log(
`Weight found. Current weight is: ${DataSnapshot.val()} kg`
);
return DataSnapshot.val();
} else {
console.log("Weight wasn't found");
}
} catch (error) {
console.log(error);
}
});
};
HomeScreen.js
// Modules
import { react, useState, useEffect } from "react";
import { Text, TouchableOpacity, View, TextInput, Image } from "react-native";
import { LogOutButton } from "../Components/LogOutButton";
import { auth, writeUserData, database, readWeight } from "../firebase";
// Stylesheet
import { styles } from "../Stylesheet/Stylesheet";
export const HomeScreen = () => {
const user = auth.currentUser;
let currentUserWeight = readWeight(database, user.uid);
console.log("Current Weight: ", currentUserWeight);
return (
<View style={styles.profileMain}>
<View style={styles.profileInfoContainer}>
<View style={styles.HOME__profileWeightContainer}>
<Text style={styles.HOME__profileWeightText}>
Last Weight: {currentUserWeight}
</Text>
</View>
</View>
</View>
</View>
);
};
Data is loaded from Firebase asynchronously, and the return DataSnapshot.val() runs way after you actually call readWeight(database, user.uid). Adding some logging is probably the best way to see that flow.
The solution is to store the weight in the state of your component with the useState hook.
export const HomeScreen = () => {
const user = auth.currentUser;
// 👇
let { currentUserWeight, setCurrentUserWeight } = useState(0);
useEffect(() => {
const unsubscribe = get(ref(database, `users/${userId}/weight`)).then((DataSnapshot) => {
if (DataSnapshot.exists()) {
setCurrentUserWeight(DataSnapshot.val());
}
});
return () => unsubscribe();
, []}
// 👆
return (
<View style={styles.profileMain}>
<View style={styles.profileInfoContainer}>
<View style={styles.HOME__profileWeightContainer}>
<Text style={styles.HOME__profileWeightText}>
Last Weight: {currentUserWeight}
</Text>
</View>
</View>
</View>
</View>
);
};

I can't make run the blemanager.start because promise rejection id:0 null is not an object

I can't start the ble manager in my code.
I use expo.
I tried a lot of solutions I found on internet but none worked for me.
When i get out the blemanager.start my app run correctly.
I don't find any kind of doc about promise in React native... There is my code. I really hope you can help me.
import { Stylesheet, View, Text, Button, TouchableOpacity,FlatList, Alert,NativeAppEventEmitter } from 'react-native'
import donnee from '../Donnee/data'
import DataItem from './DataItem'
import FilmDetail from './FilmDetail';
import BleManager from 'react-native-ble-manager';
import React, { useState, useEffect } from 'react';
//import BleManager from 'react-native-ble-plx';
const width_proportion = '60%';
const Lwidth_proportion = '30%';
const maxwidth="100%";
const heightinside="12%";
const paddleft = '10%';
class Search extends React.Component {
componentDidMount() {
console.log('bluetooth scanner mounted');
NativeAppEventEmitter.addListener('BleManagerDiscoverPeripheral',(data) =>
{
let device = 'device found: ' + data.name + '(' + data.id + ')';
if(this.devices.indexOf(device) == -1) {
this.devices.push(device);
}
let newState = this.state;
newState.dataSource = newState.dataSource.cloneWithRows(this.devices);
this.setState(newState);
});
BleManager.start({ showAlert: false }).then(() => {
// Success code
console.log("Module initialized");
});
}
startScanning() {
console.log('start scanning');
}
render() {
return (
<View>
<View style={styles.entete}></View>
<View>
<TouchableOpacity style = {styles.filtrebtn} onPress={() => this.props.navigation.navigate("FilmDetail")}>
<Text style = {styles.textfiltre}>FILTRES</Text>
</TouchableOpacity>
<TouchableOpacity style = {styles.scan} onPress={() => this.startScanning()}>
<Text style = {styles.textscan}>SCAN</Text>
</TouchableOpacity>
</View>
<View>
<FlatList
data={donnee}
keyExtractor={(item) => item.id.toString()}
renderItem={({item}) =><DataItem donnees={item}/> } />
</View>
</View>
)
}
}
export default Search
expo can not work with the ble-manager. You need to use the native package by running the
npx react-native init AwesomeProject
and you need mac not a window

React Native is Not fetching the latest data from API call

I sicerely Apologies if this has been asked before. I am a bit new to react native and react in general.
my react nativee code is not fetcing the latest data
see the code for the list component below
I would deeply appreciate it if you can tell me why this is happening and how to make it pick the latest data
import React, { Component } from "react";
import {
FlatList,
Text,
View,
StyleSheet,
ScrollView,
ActivityIndicator
} from "react-native";
import Constants from "expo-constants";
import { createStackNavigator } from "#react-navigation/stack";
import { toCommaAmount } from "./utilities";
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={ExpenseList} />
<Stack.Screen name="NewTransaction" component={ExpenseForm} />
</Stack.Navigator>
);
}
function Item({ title }) {
return (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
}
class ExpenseList extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: null
};
}
componentDidMount() {
return fetch("https://example.com/expense/api/get_all.php")
.then(response => response.json())
.then(responseJson => {
this.setState({
isLoading: false,
dataSource: responseJson.items
});
})
.catch(error => console.log(error));
}
render() {
if (this.state.isLoading) {
return (
<View style={styles.container}>
<ActivityIndicator />
</View>
);
} else {
let myExpenses = this.state.dataSource.map((val, key) => {
return (
<View key={key} style={styles.item}>
<Text>
{val.title} {toCommaAmount(val.amount)}
</Text>
<Text>{val.date_time}</Text>
</View>
);
});
return <View style={styles.container}>{myExpenses}</View>;
}
}
}
export default ExpenseList;
ComponentDidMount is a void function. I assume you have this problem because you try to return the result of the fetch execution.
Can you remove your api call out of componentDidMount(), because it gets invoked only once. Rename it to getRealData() and attach it to a button click. So every click on button will being up latest data from backend.

TypeError: undefined is not an object(evaluating '_props.listMessagesQuery.listMessages') in ReactNative

Iam new to react-native and aws appsync.We are trying to display a list of messages.But when i run react-native run-android it is throwing an error saying
TypeError: undefined is not an object(evaluating '_props.listMessagesQuery.listMessages')
[Below is the screenshot url of the error]
https://i.stack.imgur.com/b1Wlj.png
Chat.js
import React,{Component} from 'react';
import ChatInput from './ChatInput';
import ChatMessages from './ChatMessages';
import { graphql, compose } from 'react-apollo';
import listMessages from './querys/listMessages';
import createMessage from './querys/createMessage';
import gql from 'graphql-tag';
import {
Platform,
StyleSheet,
Text,
View,
scrollIntoView
} from 'react-native';
class Chat extends Component {
state = {
message: '',
}
render() {
return (
<View className='Chat'>
<ChatMessages
messages={this.props.listMessagesQuery.listMessages || []}
endRef={this._endRef}
/>
<ChatInput
message={this.state.message}
onTextInput={(message) => this.setState({message})}
onResetText={() => this.setState({message: ''})}
onSend={this._onSend}
/>
</View>
);
}
_onSend = () => {
//console.log(`Send: ${this.state.message}`)
this.props.createMessageMutation({
variables: {
text: this.state.message,
sentById: this.props.userId
}
})
}
/*
* AUTO SCROLLING
*/
_endRef = (element) => {
this.endRef = element
}
componentDidUpdate(prevProps) {
// scroll down with every new message
if (prevProps.listMessagesQuery.listMessages !== this.props.listMessagesQuery.listMessages && this.endRef) {
this.endRef.scrollIntoView()
}
}
}
export default compose(
graphql(listMessages, {
options: {
fetchPolicy: 'cache-and-network'
},
props: (props) => ({
posts: props.listMessagesQuery.listMessages && props.listMessagesQuery.listMessages.Message,
})
}))(Chat)
App.js
import React,{ Component} from 'react';
import * as AWS from 'aws-sdk';
import {
Platform,
StyleSheet,
Text,
View
} from 'react-native';
import gql from 'graphql-tag';
import { graphql,compose} from 'react-apollo';
import generateStupidName from 'sillyname';
import localStorage from 'react-native-sync-localstorage';
import Chat from './Chat';
import { Async } from 'react-async-await';
import createPerson from './querys/createPerson';
const CHAT_USER_NAME_KEY = 'CHAT_USER_NAME'
const CHAT_USER_ID_KEY = 'CHAT_USER_ID'
class App extends Component {
async componentDidMount() {
let name = localStorage.getItem(CHAT_USER_NAME_KEY)
if (!name) {
name = generateStupidName()
const result = await this.props.createPersonMutation({
variables: { name }
})
localStorage.setItem(CHAT_USER_NAME_KEY, result.data.createPerson.name);
localStorage.setItem(CHAT_USER_ID_KEY, result.data.createPerson.id);
}
}
render() {
const name = localStorage.getItem(CHAT_USER_NAME_KEY)
const userId = localStorage.getItem(CHAT_USER_ID_KEY)
return (
<View style={styles.container}>
<Chat name={name} userId={userId} />
</View>
);
}
}
// const createPerson =gql`
// mutation createPerson($name:String!){
// createPerson(input :{
// name : $name
// }){
// id
// name
// }
// }
// `
// export default graphql(createPerson,{name:'createPersonMutation'})(App)
export default compose(
graphql(createPerson, {name:'createPersonMutation'}))(App)
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
Iam not understanding this error Please help me.Thanks! in Advance
Please check the format of
this.props.listMessagesQuery.listMessages
As the error defined that particular data or props you are passing are not an object.
console.log(this.props.listMessagesQuery.listMessages)
check if you find it in current formate. If you don't find anything share you this console.log result. Hope it helps you
you are not sending listMessagesQuery.listMessages as a props to Chat.js component you are only sending name and userId as props to Chat component
your existing code in App.js
<Chat name={name} userId={userId} />
you need to send
<Chat name={name} userId={userId} listMessagesQuery={}/>

Resources