Skip to content

Instantly share code, notes, and snippets.

@rahsheen
Created March 21, 2020 15:33
Show Gist options
  • Select an option

  • Save rahsheen/363b2159a3692936b194840d67367873 to your computer and use it in GitHub Desktop.

Select an option

Save rahsheen/363b2159a3692936b194840d67367873 to your computer and use it in GitHub Desktop.
Component to allow display and upload of image to Firebase.
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