Created
March 21, 2020 15:33
-
-
Save rahsheen/363b2159a3692936b194840d67367873 to your computer and use it in GitHub Desktop.
Component to allow display and upload of image to Firebase.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React, {Component} from 'react' | |
| import {TouchableOpacity, StyleSheet, Image, Alert, View} from 'react-native' | |
| import ImagePicker from 'react-native-image-picker' | |
| import Permissions from 'react-native-permissions' | |
| import firebase from 'react-native-firebase' | |
| import {Avatar} from 'react-native-elements' | |
| const options = { | |
| title: 'Select Avatar', | |
| storageOptions: { | |
| skipBackup: true, | |
| path: 'images', | |
| }, | |
| } | |
| interface ProfilePhotoProps { | |
| onChange: () => void | |
| size: number | |
| displayOnly: boolean | |
| onPress: () => void | |
| uid: string | |
| backgroundColor: string | |
| } | |
| export default class ProfilePhoto extends Component< | |
| ProfilePhotoProps, | |
| {avatar: string|null; uid?: string; loading: boolean} | |
| > { | |
| state = { | |
| avatar: null, | |
| uid: '', | |
| loading: true, | |
| } | |
| userRef = firebase.firestore().collection('users') | |
| componentDidMount() { | |
| const currentUser = firebase.auth().currentUser | |
| if (!currentUser) return | |
| const {uid} = currentUser | |
| this.userRef.doc(uid).onSnapshot(userDoc => { | |
| console.log(`Got Doc`) | |
| if (userDoc.exists) { | |
| const {avatar} = userDoc.data() | |
| console.log(`Got Avatar`, avatar) | |
| this.setState({ | |
| avatar, | |
| uid, | |
| loading: false, | |
| }) | |
| } | |
| }) | |
| !this.props.displayOnly && this._checkCameraAndPhotos() | |
| } | |
| // Check the status of multiple permissions | |
| _checkCameraAndPhotos = () => { | |
| Permissions.checkMultiple(['camera', 'photo']).then(response => { | |
| //response is an object mapping type to permission | |
| this.setState( | |
| { | |
| cameraPermission: response.camera, | |
| photoPermission: response.photo, | |
| }, | |
| () => { | |
| const {cameraPermission, photoPermission} = this.state | |
| if ( | |
| cameraPermission == 'undetermined' || | |
| photoPermission == 'undetermined' | |
| ) { | |
| this._alertForPhotosPermission() | |
| } | |
| }, | |
| ) | |
| }) | |
| } | |
| _requestPermission = async () => { | |
| try { | |
| const photoPermission = await Permissions.request('photo') | |
| const cameraPermission = await Permissions.request('camera') | |
| this.setState({photoPermission, cameraPermission}) | |
| } catch (error) { | |
| console.log(`Error getting photo/camera permissions`, error) | |
| } | |
| } | |
| _alertForPhotosPermission() { | |
| Alert.alert( | |
| 'Can we access your photos?', | |
| 'We need access so you can set your profile pic', | |
| [ | |
| { | |
| text: 'Not Now', | |
| onPress: () => console.log('Permission denied'), | |
| style: 'cancel', | |
| }, | |
| {text: 'Ok', onPress: this._requestPermission}, | |
| ], | |
| ) | |
| } | |
| showImagePicker = () => { | |
| ImagePicker.showImagePicker(options, response => { | |
| if (response.didCancel) { | |
| console.log('User cancelled image picker') | |
| } else if (response.error) { | |
| console.log('ImagePicker Error: ', response.error) | |
| } else if (response.customButton) { | |
| console.log('User tapped custom button: ', response.customButton) | |
| } else { | |
| this.setState({ | |
| avatar: response.uri, | |
| }) | |
| this.setAvatar(response.uri) | |
| } | |
| }) | |
| } | |
| setAvatar = (image: string) => { | |
| const {uid} = this.state | |
| const {onChange} = this.props | |
| const avatarRef = firebase.storage().ref(`/users/avatar/${uid}`) | |
| const unsubscribe = avatarRef.putFile(image).on( | |
| 'state_changed', | |
| snapshot => { | |
| onChange && onChange(snapshot.downloadURL) | |
| if (snapshot.state === 'success') { | |
| this.userRef | |
| .doc(uid) | |
| .update({avatar: snapshot.downloadURL}) | |
| .catch(e => console.log("Couldn't upload photo", e)) | |
| } | |
| }, | |
| error => { | |
| console.log('ProfilePhoto Error', error) | |
| unsubscribe() | |
| }, | |
| // Success | |
| () => unsubscribe(), | |
| ) | |
| } | |
| extraStyles = () => { | |
| const size = this.props.size || 90 | |
| const backgroundColor = this.props.backgroundColor || 'white' | |
| return { | |
| width: size, | |
| height: size, | |
| backgroundColor, | |
| } | |
| } | |
| render() { | |
| const {onPress, size, displayOnly, ...rest} = this.props | |
| const onPressAction = onPress || this.showImagePicker | |
| return ( | |
| <View> | |
| <Avatar | |
| rounded | |
| size={size} | |
| source={{ | |
| uri: this.state.avatar, | |
| }} | |
| title={this.state.loading ? "..." : ""} | |
| onPress={displayOnly ? () => {} : onPressAction} | |
| containerStyle={{ | |
| borderWidth: 2, | |
| borderColor: '#b8852c', | |
| alignSelf: 'center', | |
| }} | |
| {...rest} | |
| /> | |
| </View> | |
| ) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment