How to get user id from firebase in react native? - javascript

I need your help I'm using firebase for my app. I'm trying to get the users ID not the logged users no all users I have. I want to show their (uid) simply like in an alert for each user. Also, I'm showing them in a flatlist and when I set item.uid in an alert it shows (undefined). But, all the other data of the user is shown correctly. This what I did until now:
**
users.js
**
export default class usersList extends React.Component{
state = {
loading: false,
uid: '',
users: [],
items: []
};
componentDidMount() {
let itemsRef = f.database().ref('users').once('value').then(snapshot => {
var data = snapshot.val();
var items = Object.values(data);
this.setState({items});
console.log(snapshot.val())
});
}
renderItem({item}) {
return (
<View key={index} style={{width: '100%', overflow:'hidden', marginBottom: 5, justifyContent:'space-between', borderBottomWidth:1, borderColor: 'grey'}}>
<View>
<View style={{padding:5, width:'100%', flexDirection: 'row', justifyContent: 'space-between'}}>
<Text>{item.email}</Text>
</View>
</View>
</View>
)
}
render() {
return (
<View style={styles.container}>
<ScrollView>
{
this.state.items.length > 0
? <ItemComponent items={this.state.items} navigation={this.props.navigation} />
: <Text>No stores</Text>
}
</ScrollView>
</View>
);
}
}
//ItemComponent.js
export default class ItemComponent extends Component {
static propTypes = {
items: PropTypes.array.isRequired
};
render() {
return (
<View style={styles.itemsList}>
{this.props.items.map((item, index) => {
return (
<View key={index}>
<TouchableOpacity
onPress={ () => alert(item.uid)}>
<Text style={styles.itemtext}>{item.email}</Text>
</TouchableOpacity>
</View>
)
})}
</View>
);
}
}

firebase.database().ref('user').on('value', (datasnapshot) => {
this.setState({
_id: datasnapshot.key
});`

This solution worked for me
<Text style={styles.yourStyleHere}>UID: {auth.currentUser?.uid} </Text>

Related

Mapping over sent props using .map react native

i have two components one is called homeScreen the second is card i do fetch data in homeScreen i set it to state after i do send state through props to my card component .
Now my card components should generate 9 cards accoridng to the data i am sending through to it so i did map and i am getting this error
TypeError: Cannot read property '0' of undefined.
i tried to console.log props inside Card component and i could see data but for some reason the map isnt working
Card.js
const Card = props => {
Array.from({length: 9}).map((i, index) => {
console.log(props);
return (
<View style={{flex: 1}}>
<Text style={{flex: 1, backgroundColor: 'red'}}>
{props.title[1] ? `${props.title[index]}` : 'Loading'}
</Text>
<Text style={{flex: 1, backgroundColor: 'blue'}}>{props.rating[index]}</Text>
</View>
);
});
};
export default Card;
homeScreen.js
export default class HomeScreen extends React.Component {
state = {
title: [],
image: [],
rating: [],
isLoading: true,
};
componentDidMount() {
this.getData();
}
titleSend = () => {
if (!this.state.isLoading) {
{
Array.from({length: 9}).map((i, index) => {
return this.state.title[index];
});
}
}
};
imageSetter = () => {
Array.from({length: 9}).map((i, keys) => {
return (
<Image
key={keys}
style={{width: 50, height: 50, flex: 1}}
source={{uri: this.state.image[keys]}}
/>
);
});
};
getData = () => {
const requestUrls = Array.from({length: 9}).map(
(_, idx) => `http://api.tvmaze.com/shows/${idx + 1}`,
);
const handleResponse = data => {
const shows = data.map(show => show.data);
this.setState({
isLoading: false,
title: shows.map(show => show.name),
image: shows.map(show => show.image.medium),
rating: shows.map(show => show.rating.average),
});
// console.log(this.state);
};
const handleError = error => {
this.setState({
isLoading: false,
});
};
Promise.all(requestUrls.map(url => axios.get(url)))
.then(handleResponse)
.catch(handleError);
};
render() {
const {isLoading, title, image, rating} = this.state;
if (isLoading) {
return <ActivityIndicator size="large" color="#0000ff" />;
}
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<ScrollView style={{flex: 1, backgroundColor: 'red'}}>
<Card title={this.state.title} />
</ScrollView>
<Text>here images</Text>
</View>
);
}
}
None of your functions/methods using Array.from are returning a value.
For example your Card component:
const Card = props => {
// note addition of `return` statement
return Array.from({length: 9}).map((i, index) => {
console.log(props);
return (
<View style={{flex: 1}}>
<Text style={{flex: 1, backgroundColor: 'red'}}>
{props.title[1] ? `${props.title[index]}` : 'Loading'}
</Text>
<Text style={{flex: 1, backgroundColor: 'blue'}}>{props.rating[index]}</Text>
</View>
);
});
};
export default Card;
The titleSend and imageSetter methods have a similar issue.
The index error is because you're not passing an rating prop to the Card component but you're accessing props.rating[0], props.rating[1], etc.
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<ScrollView style={{flex: 1, backgroundColor: 'red'}}>
// missing `rating` prop
<Card title={this.state.title} />
</ScrollView>
<Text>here images</Text>
</View>
);

How do I navigate between List and Item?

I am trying to open an item from my list but my item code is in another js. When I try to use onPress method there is no action. Also I am using Swipeout.
Here is my JobList.js where I am rendering the list of my items.
class JobList extends Component {
onJobDetails = (job) => {
this.props.navigate('JobDetails', job);
}
render() {
const { navigation } = this.props;
var renderJobs = () => {
return this.props.jobs.map((job) => {
return (
<JobItem
key={job._id}
title={job.title}
shortDescription={job.shortDescription}
logo={job.avatar}
company={job.company}
id={job._id}
dispatch={this.props.dispatch}
onPress={() => this.onJobDetails(job)}
/>
)
})
}
return (
<View style={styles.container}>
<ScrollView>
{renderJobs()}
</ScrollView>
</View>
);
}
};
And here is my JobItem.js
class JobItem extends Component {
render() {
return (
<Swipeout {...swipeSettings}>
<View style={styles.jobContainer}>
<View>
<Text style={styles.postTitle}>{this.props.title}</Text>
<Text style={styles.postShortDescription}>{this.props.shortDescription}</Text>
</View>
<View>
<Image
style={styles.postLogo}
source={{uri: '' + this.props.logo + ''}}/>
</View>
</View>
</Swipeout>
)
}
};
Any idea how shall I fix this?
You need to pass onPress prop to the child component in order for it to work.
<Swipeout {...swipeSettings}>
<TouchableWithoutFeedback onPress={this.props.onPress}>
//... other children here
</TouchableWithoutFeedback>
</Swipeout>

Hide/Show button in React Native Toolbar

I am trying to hide/show a button in header of a React Native Toolbar. I would like the buttons to show once the user logs in. I get the error undefined is not an object on this.state.status. How can I get the state in the toolbar?
export default class TestSC extends React.Component {
constructor(){
super();
this.state ={
status:false
}
}
static navigationOptions = ({navigation})=> {
return {
title: 'Tin Tin Foil',
headerRight: (
<View style={styles.twoButtonView}>
{(this.state.status == true) ?
<TouchableOpacity onPress={this._refreshButtonPress}>
<Image source={require('../img/ic_search_white.png')} style={styles.refrgeshButton} />
</TouchableOpacity>
: null}
<Button
onPress={() => navigation.navigate('Login')}
title="Login" color="#fff" />
</View>
),
}};
toggleStatus(){
this.setState({
status:!this.state.status
});
console.log('toggleStatus: '+ this.state.status);
}
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Test</Text>
<TouchableHighlight onPress={()=>this.toggleStatus()}>
<Text> Click Me Toggle </Text>
</TouchableHighlight>
</View>
);
}
}
You can use navigation params to achieve this.
While setting component state, you need to set Navigator params as well.
this.props.navigation.setParams({
status: true
})
And use navigator params in the header.
navigation.state.params.status == true
Complete Example
export default class TestSC extends React.Component {
constructor() {
super();
this.state = {
status: false
}
}
static navigationOptions = ({navigation, screenProps}) => {
if (!navigation.state.params) {
navigation.state.params = {}
}
return {
title: 'Tin Tin Foil',
headerRight: (
<View style={styles.twoButtonView}>
{(navigation.state.params.status == true) ?
<TouchableOpacity onPress={this._refreshButtonPress}>
<Text>Login</Text>
</TouchableOpacity>
: null}
</View>
),
}
};
toggleStatus() {
this.setState(pre => {
pre.status = !pre.status
this.props.navigation.setParams({
status: pre.status
})
return pre
})
console.log('toggleStatus: ' + this.state.status);
}
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Test</Text>
<TouchableHighlight onPress={()=>this.toggleStatus()}>
<Text> Click Me Toggle </Text>
</TouchableHighlight>
</View>
);
}
}

How refresh the ListView Component in react native?

I'm trying to create a todo list, then I'm trying to use this checkbox package
react-native-check-box
I don't know if this issue come from that package
when I click the checkbox and click the delete button this is what happen
And here is my code for displaying the list
interface TodoProps{
todo: TodoModel;
ter:string;
}
interface TodoState{
dataSource: any;
myTodo: Array<ITodo>;
}
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => true});
export default class Todo extends React.Component <TodoProps,TodoState>{
constructor(props:TodoProps) {
super(props);
this.state = {
dataSource: ds.cloneWithRows([]), // or put your initial data here
myTodo: []
};
}
componentWillReceiveProps = (nextProps) => {
console.log(this.state.myTodo);
let data = {
title: nextProps.ter,
isChecked: false
};
let todoList = this.state.myTodo;
if (nextProps.ter) {
todoList.push(data);
}
this.setState({
myTodo: todoList
});
}
onDelete(){
let todos = this.state.myTodo.filter((todo:ITodo) => {
return !todo.isChecked;
});
this.setState({
myTodo: todos
});
}
render() {
let dataSource = this.state.dataSource.cloneWithRows(this.state.myTodo);
return (
<View style={styles.container}>
<View style={styles.box2}>
<ListView enableEmptySections={true} dataSource={dataSource} renderRow={(rowData, sectionID, rowID) => <TodoList data={rowData} onClick={this.onClick.bind(this)} id={rowID} /> } />
</View>
<View style={styles.box3}>
<TouchableOpacity style={styles.bbox1} onPress={()=> alert('weee')}>
<Text style={styles.tabText}>All</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bbox2} onPress={()=> alert('weee')}>
<Text style={styles.tabText}>Complete</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bbox3} onPress={()=> alert('weee')}>
<Text style={styles.tabText}>InComplete</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bbox4} onPress={()=> this.onDestroy()}>
<Text style={styles.tabText}>Delete</Text>
</TouchableOpacity>
</View>
</View>
)
}
}
But if I console log the data. I find all isChecke: to false. Only the view of checkbox is not working. Do I need to use componentwillamount() for this?
Use the below sample code
_onRefresh() {
this.setState({refreshing: true});
// your callback function or call this.componentDidMount()
}
render() {
return (
<ListView
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this._onRefresh.bind(this)}
/>
}
...
>
...
</ListView>
);
}

React-Native Navigation without render command

Is there anyway to redirect user to a different component (also passing arguments with it) without calling render function?
almost in all tutorials i found, they use sameway :
render() {
return (
<NavigatorIOS
style={styles.container}
initialRoute=\{\{
title: 'first',
component: First
}} />
);
}
Now see my code :
in renderRow , for touchablehighlights , i need to be able to redirect user to a page with an argument, (in this case i need to send user to component CourseDetail with argument of course_id, so i can show user course's details)
class Courses extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
loaded: false,
};
}
fetchData() {
// fetching data here
}
componentDidMount() {
this.fetchData();
}
render(){
if (!this.state.loaded) {
return this.renderLoadingView();
}
return (
<View style={{
flex: 1
}}>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
style={styles.listView}
/>
</View>
);
}
renderRow(data) {
var header = (
<View>
<View style={styles.rowContainer}>
<View style={styles.textContainer}>
<Text style={styles.title}>{data.nid}</Text>
<Text style={styles.description} numberOfLines={0}>{data.title}</Text>
</View>
</View>
<View style={styles.separator}></View>
</View>
);
///////////
var cid = [];
var content = [];
for(let x=0; x < Object.keys(data.course).length; x++){
cid[x] = data.course[x].course_id;
content.push(
<TouchableHighlight
underlayColor='#e3e0d7'
key={x}
onPress={()=>{console.log(cid[x]);}} //// i need to navigate user to a page with passing arguments (course_id in this case)
style={styles.child}
>
<Text style={styles.child}>
{data.course[x].title}
</Text>
</TouchableHighlight>
);
}
console.log(cid);
var clist = (
<View style={styles.rowContainer}>
{content}
</View>
);
////////////
return (
<Accordion
header={header}
content={clist}
easing="easeOutCubic"
/>
);
}
renderLoadingView() {
return (
<View style={styles.loading}>
<Text style={styles.loading}>
Loading Courses, please wait...
</Text>
</View>
);
}
}
module.exports = Courses;
Thanks in Advance!
By help of this Question here :
React-Native: Cannot access state values or any methods declared from renderRow
I was able to solve the issue by changing :
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
style={styles.listView}
/>
To :
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow.bind(this)}
style={styles.listView}
/>
Hope it will help others who may have the same problem.

Categories

Resources