Skip to content

Commit 09d02fa

Browse files
committed
Do upload image to firebase & get data from posts view on flatList
1 parent 0180513 commit 09d02fa

File tree

3 files changed

+183
-111
lines changed

3 files changed

+183
-111
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,11 @@
8282
20. Image Gif not fire Android
8383

8484
- https://stackoverflow.com/questions/57089042/react-native-0-60-0-0-60-x-android-for-animated-gif-support
85+
86+
21. Custom tabbar
87+
88+
- https://dev.to/hrastnik/lets-create-a-custom-animated-tab-bar-with-react-native-3496
89+
90+
22. Handle ID javascript with firebase
91+
92+
- https://stackoverflow.com/questions/56144736/react-native-firebase-display-array-of-objects-using-flatlist

src/screens/Home.js

Lines changed: 93 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,88 @@
1-
import React, {Component} from 'react';
1+
import React, {Component, useEffect, useState} from 'react';
22
import {Text, StyleSheet, View, FlatList, Image} from 'react-native';
33
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
44
import moment from 'moment';
5+
import firebase from 'firebase';
56

6-
posts = [
7-
{
8-
id: '1',
9-
name: 'Joe McKay',
10-
text:
11-
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
12-
timestamp: 1569109273726,
13-
avatar: require('../assets/avatar/image1.png'),
14-
image: require('../assets/onboarding/image1.gif'),
15-
},
16-
{
17-
id: '2',
18-
name: 'Karyn Kim',
19-
text:
20-
'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
21-
timestamp: 1569109273726,
22-
avatar: require('../assets/avatar/image1.png'),
23-
image: require('../assets/onboarding/image2.gif'),
24-
},
25-
{
26-
id: '3',
27-
name: 'Emerson Parsons',
28-
text:
29-
'Amet mattis vulputate enim nulla aliquet porttitor lacus luctus. Vel elit scelerisque mauris pellentesque pulvinar pellentesque habitant.',
30-
timestamp: 1569109273726,
31-
avatar: require('../assets/avatar/image1.png'),
32-
image: require('../assets/onboarding/image3.gif'),
33-
},
34-
{
35-
id: '4',
36-
name: 'Kathie Malone',
37-
text:
38-
'At varius vel pharetra vel turpis nunc eget lorem. Lorem mollis aliquam ut porttitor leo a diam sollicitudin tempor. Adipiscing tristique risus nec feugiat in fermentum.',
39-
timestamp: 1569109273726,
40-
avatar: require('../assets/avatar/image1.png'),
41-
image: require('../assets/onboarding/image1.gif'),
42-
},
43-
];
7+
// posts = [
8+
// {
9+
// id: '1',
10+
// name: 'Joe McKay',
11+
// text:
12+
// 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
13+
// timestamp: 1569109273726,
14+
// avatar: require('../assets/avatar/image1.png'),
15+
// image: require('../assets/onboarding/image1.gif'),
16+
// },
17+
// {
18+
// id: '2',
19+
// name: 'Karyn Kim',
20+
// text:
21+
// 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
22+
// timestamp: 1569109273726,
23+
// avatar: require('../assets/avatar/image1.png'),
24+
// image: require('../assets/onboarding/image2.gif'),
25+
// },
26+
// {
27+
// id: '3',
28+
// name: 'Emerson Parsons',
29+
// text:
30+
// 'Amet mattis vulputate enim nulla aliquet porttitor lacus luctus. Vel elit scelerisque mauris pellentesque pulvinar pellentesque habitant.',
31+
// timestamp: 1569109273726,
32+
// avatar: require('../assets/avatar/image1.png'),
33+
// image: require('../assets/onboarding/image3.gif'),
34+
// },
35+
// {
36+
// id: '4',
37+
// name: 'Kathie Malone',
38+
// text:
39+
// 'At varius vel pharetra vel turpis nunc eget lorem. Lorem mollis aliquam ut porttitor leo a diam sollicitudin tempor. Adipiscing tristique risus nec feugiat in fermentum.',
40+
// timestamp: 1569109273726,
41+
// avatar: require('../assets/avatar/image1.png'),
42+
// image: require('../assets/onboarding/image1.gif'),
43+
// },
44+
// ];
45+
46+
export default function HomeScreen() {
47+
const [posts, setPosts] = useState([]);
48+
useEffect(() => {
49+
firebase
50+
.firestore()
51+
.collection('posts')
52+
.get()
53+
.then(snapshot => {
54+
if (snapshot.empty) {
55+
console.log('No matching documents.');
56+
return;
57+
}
58+
59+
// snapshot.forEach(doc => {
60+
// console.log(doc.id, '=>', doc.data());
61+
// return {...doc.id, ...doc.data()};
62+
// });
63+
64+
var returnArray = [];
65+
66+
snapshot.forEach(function(doc) {
67+
let item = {};
68+
item = doc.data();
69+
item.id = doc.id;
70+
item.avatar = require('../assets/avatar/image1.png');
71+
returnArray.push(item);
72+
});
73+
74+
// console.log(returnArray);
75+
76+
setPosts(returnArray);
77+
})
78+
.catch(err => {
79+
console.log('Error getting documents', err);
80+
});
81+
});
4482

45-
export default class BirthdayScreen extends Component {
4683
renderPost = post => {
4784
return (
48-
<View style={styles.feedItem}>
85+
<View key={post.id} style={styles.feedItem}>
4986
<Image source={post.avatar} style={styles.avatar} />
5087
<View style={{flex: 1}}>
5188
<View
@@ -55,7 +92,7 @@ export default class BirthdayScreen extends Component {
5592
alignItems: 'center',
5693
}}>
5794
<View>
58-
<Text style={styles.name}>{post.name}</Text>
95+
<Text style={styles.name}>{post.uid}</Text>
5996
<Text style={styles.timestamp}>
6097
{moment(post.timestamp).fromNow()}
6198
</Text>
@@ -65,7 +102,7 @@ export default class BirthdayScreen extends Component {
65102
</View>
66103
<Text style={styles.post}>{post.text}</Text>
67104
<Image
68-
source={post.image}
105+
source={{uri: post.image}}
69106
style={styles.postImage}
70107
resizeMode="cover"
71108
/>
@@ -83,22 +120,20 @@ export default class BirthdayScreen extends Component {
83120
);
84121
};
85122

86-
render() {
87-
return (
88-
<View style={styles.container}>
89-
<View style={styles.header}>
90-
<Text style={styles.headerTitle}>Feed</Text>
91-
</View>
92-
93-
<FlatList
94-
style={styles.feed}
95-
data={posts}
96-
renderItem={({item}) => this.renderPost(item)}
97-
keyExtractor={item => item.id}
98-
showsVerticalScrollIndicator={false}></FlatList>
123+
return (
124+
<View style={styles.container}>
125+
<View style={styles.header}>
126+
<Text style={styles.headerTitle}>Feed</Text>
99127
</View>
100-
);
101-
}
128+
129+
<FlatList
130+
style={styles.feed}
131+
data={posts}
132+
renderItem={({item}) => renderPost(item)}
133+
keyExtractor={item => item.id}
134+
showsVerticalScrollIndicator={false}></FlatList>
135+
</View>
136+
);
102137
}
103138

104139
const styles = StyleSheet.create({

src/screens/Post.js

Lines changed: 82 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ import SafeAreaView from 'react-native-safe-area-view';
1212
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
1313
// import {request, PERMISSIONS} from 'react-native-permissions';
1414
import ImagePicker from 'react-native-image-picker';
15-
// import AsyncStorage from '@react-native-community/async-storage';
16-
import firebase, {firestore} from 'firebase';
15+
import firebase from 'firebase';
1716
import 'firebase/firestore';
18-
// import Firebase from '../tools/firebase';
1917

2018
// More info on all the options is below in the API Reference... just some common use cases shown here
2119
const options = {
@@ -29,20 +27,10 @@ const options = {
2927

3028
export default function PostScreen(props) {
3129
const navigation = useNavigation();
32-
const {navigate} = navigation;
3330

3431
const [text, setText] = useState('');
3532
const [image, setImage] = useState(null);
3633

37-
// useEffect(() => {
38-
// _bootstrap();
39-
// });
40-
41-
// async function _bootstrap() {
42-
// const newImage = await AsyncStorage.getItem('image');
43-
// setImage(JSON.parse(newImage));
44-
// }
45-
4634
function _pickImage() {
4735
ImagePicker.launchImageLibrary(options, async response => {
4836
// console.log('Response = ', response);
@@ -60,64 +48,105 @@ export default function PostScreen(props) {
6048
// const source = { uri: 'data:image/jpeg;base64,' + response.data };
6149

6250
setImage(source);
63-
// await AsyncStorage.setItem('image', JSON.stringify(source));
6451
}
6552
});
6653
}
6754

68-
async function _addPost({text, localUri}) {
69-
firebase
70-
.firestore()
71-
.collection('posts')
72-
.add({
73-
uid: Math.floor(Math.random() * 100000),
74-
text: text,
75-
timestamp: Date.now(),
76-
})
77-
.then(res => {
78-
console.log(res);
79-
navigation.goBack();
80-
})
81-
.catch(err => console.log(err));
55+
function _uid() {
56+
return (firebase.auth().currentUser || {}).uid;
8257
}
8358

8459
function _onPost() {
85-
_addPost({text: text.trim(), localUri: image});
60+
_addPost({text: text.trim(), localUri: image.uri});
8661
}
8762

88-
async function uploadPhotoAsync({uri}) {
89-
const path = `photos/${uid}/${Date.now()}.jpg`;
90-
63+
function _uploadPhotoAsync(localUri, path) {
9164
return new Promise(async (res, rej) => {
92-
console.log('upload1');
93-
console.log('uri', uri);
94-
const response = await fetch(uri);
95-
console.log('upload2');
65+
const response = await fetch(localUri);
9666

67+
// File or Blob named mountains.jpg
9768
const file = await response.blob();
98-
console.log('upload3');
99-
100-
let upload = firebase
101-
.storage()
102-
.ref(path)
103-
.put(file);
104-
105-
upload.on(
106-
'state_changed',
107-
snapshot => {},
108-
err => {
109-
rej(err);
69+
70+
// Create the file metadata
71+
var metadata = {
72+
contentType: null,
73+
};
74+
75+
// Create a root reference
76+
var storageRef = firebase.storage().ref();
77+
78+
// Upload file and metadata to the object 'images/mountains.jpg'
79+
var uploadTask = storageRef.child(path).put(file, metadata);
80+
81+
// Listen for state changes, errors, and completion of the upload.
82+
uploadTask.on(
83+
firebase.storage.TaskEvent.STATE_CHANGED, // or 'state_changed'
84+
snapshot => {
85+
// Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
86+
var progress =
87+
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
88+
console.log('Upload is ' + progress + '% done');
89+
switch (snapshot.state) {
90+
case firebase.storage.TaskState.PAUSED: // or 'paused'
91+
console.log('Upload is paused');
92+
break;
93+
case firebase.storage.TaskState.RUNNING: // or 'running'
94+
console.log('Upload is running');
95+
break;
96+
}
11097
},
111-
async () => {
112-
const url = await upload.snapshot.ref.getDownloadURL();
113-
res(url);
98+
error => {
99+
// A full list of error codes is available at
100+
// https://firebase.google.com/docs/storage/web/handle-errors
101+
switch (error.code) {
102+
case 'storage/unauthorized':
103+
// User doesn't have permission to access the object
104+
break;
105+
106+
case 'storage/canceled':
107+
// User canceled the upload
108+
break;
109+
110+
case 'storage/unknown':
111+
// Unknown error occurred, inspect error.serverResponse
112+
break;
113+
}
114+
rej(error);
115+
},
116+
() => {
117+
// Upload completed successfully, now we can get the download URL
118+
uploadTask.snapshot.ref.getDownloadURL().then(downloadURL => {
119+
console.log('File available at', downloadURL);
120+
res(downloadURL);
121+
});
114122
},
115123
);
116124
});
117125
}
118126

119-
function uid() {
120-
return (firebase.auth().currentUser || {}).uid;
127+
async function _addPost({text, localUri}) {
128+
const remoteUri = await _uploadPhotoAsync(
129+
localUri,
130+
`photos/${_uid()}/${Date.now()}`,
131+
);
132+
133+
// console.log('remoteUri', remoteUri);
134+
135+
firebase
136+
.firestore()
137+
.collection('posts')
138+
.add({
139+
uid: _uid(),
140+
text: text,
141+
timestamp: Date.now(),
142+
image: remoteUri,
143+
})
144+
.then(res => {
145+
setText('');
146+
setImage(null);
147+
navigation.goBack();
148+
})
149+
.catch(err => console.log(err));
121150
}
122151

123152
return (

0 commit comments

Comments
 (0)