【问题标题】:How to DIsplay images from Firebase Storage in React Native in using snapshot?如何使用快照在 React Native 中显示来自 Firebase 存储的图像?
【发布时间】:2021-09-21 23:32:43
【问题描述】:

我是 React Native 的新手,使用 Expo,我能够成功设置一个将图片上传到 Firebase 存储的应用,但现在我无法在应用(主屏幕)上显示这些图片。

如何将最新图像拉入/显示到 FlatList 或类似的可滚动组件中?我已经通过 StackOverflow 查看了以前的答案,但没有运气。 感谢您的帮助!

HomeS.js:

export default class HomeS extends React. Component {

    renderPost = post => {
        return (
            <View style={styles.feedItem}>
                <Image source={post.avatar} style={styles.avatar} />
                <View style={{ flex: 1 }}>
                    <View style={{ flexDirection: "row", justifyContent: "space-between", alignItems: "center" }}>
                        <View>
                            <Text style={styles.name}>{post.name}</Text>
                            <Text style={styles.timestamp}>{moment(post.timestamp).fromNow()}</Text>
                        </View>

                        <Feather name="more-horizontal" size={24} color="#73788B"  /> 
                    </View>
                    <Text style={styles.post}>{post.text}</Text>
                    <Image source={post.image} style={styles.postImage} resizeMode="cover" />
                    <View style={{ flexDirection: "row" }}>
                        <Feather name="heart" size={24} color="#73788B" style={{marginRight:16}}  />
                        <Ionicons name="chatbox" size={24} color="#73788B" />
                    </View>
                </View>
            </View>
        );
    };

    constructor(props){
        super(props);
        this.state=({
            posts:[],
            newtext:'',
            loading:false,
        });
        this.ref = firebase.firestore().collection('posts').orderBy("timestamp", "desc");
        }
    
   
    componentDidMount() {

        const {imageName} = this.state;
        let imageRef = firebase.storage().ref('photos' + imageName);
        imageRef
        .getDownloadURL()
        .then((url) => {
    //from url you can fetched the uploaded image easily
        this.setState({profileImageUrl: url});
        })
        .catch((e) => console.log('getting downloadURL of image error => ', e));
        
        this.unsubscribe = this.ref.onSnapshot((querySnapshot => {
            const example = [];
            
            querySnapshot.forEach((doc, index)=>{
                example.push({
                    name: doc.data().name, //Work
                    id: doc.data().id,  //Work
                    text: doc.data().text,  //Work
                    timestamp: doc.data().timestamp,  //Work
                    imageRef: doc.data().imageRef // Not Working
                    
                   
                });
            });
            this.setState({
                posts:example,
                loading: false,
            });
        }));
    }
    

    onPressPost = () => {
        this.ref.add({
            textname : this.props.text,localUri: this.state.image

        }).then((data)=>{
            console.log(`adding data = ${data}`);
            this.setState({
                newtext:'',
                image:null,
                loading:true
            });
        }).catch((error)=>{
            console.log(`error to add doc = ${error}`);
            this.setState({
                newtext:'',
                loading:true
            });
        });
    }


    render() {
        return (
            <View style={styles.container}>
                <View style={styles.header}>
                    <Text style={styles.headerTitle}>Feed</Text>
                </View>

                <FlatList
                    style={styles.feed}
                    data={this.state.posts}
                    renderItem={({ item }) => this.renderPost(item)}
                    keyExtractor={item => item.id}
                    showsVerticalScrollIndicator={false}
                ></FlatList>
            </View>
        );
    }

【问题讨论】:

  • 有人吗?
  • 一会儿我会回答的

标签: react-native


【解决方案1】:

要在 Firebase 存储中显示图像,您将按照以下步骤操作:-

  1. 将图片上传到 Firebase
  2. 获取下载链接
  3. 使用图片源中的下载链接

首先你会从输入类型文件中获取文件对象

<input type="file" onchange={(e)=>(this.uploadImage(e))}

上传图片并获取下载地址

uploadImage = async (e) => {

    var files = e.target.files
    var image = files[0]

    const Buffer = await image.arrayBuffer() // convert img to buffer 

    var storageRef = firebase.storage().ref('/MyPix')
    var picPath = "pic_awesome.jpg"
    var ref = storageRef.child(picPath)
    var metadata = { contentType: 'image/jpeg', public: true }

    await ref.put(Buffer, metadata)
    var downloadUrl = await ref.getDownloadURL()
    console.log('Download Url :: ' + downloadUrl)
    return downloadUrl;    
}

现在显示来自下载地址的图片

 <Image
      style={{width: 50, height: 50}}
      source={{uri: this.state.ImageUrl}}
    />

现在让我告诉你一种上传多张图片的高效方法

const imageList = ['https://imgpath.jpg','https://imgpath2.jpg']

const requests = imageList.map((image) => {
    return uploadImage(image)  // upload image method is given above
})

console.log(`start uploading All images in imageList in parallel`)
  const response = await Promise.all(requests)
  response.map((image)=> saveToFireStore(image))

现在将下载 url 保存到 firestore

 import { addDoc, collection , getFirestore } from "firebase/firestore"; 

...

const saveToFireStore = async (downloadUrl) => {

const db = getFirestore();
  const docRef = await addDoc(collection(db, "users"), {
    userId: "123",
    userName: "Mathison",
    profilePic: downloadUrl
  });

}

现在让我们进入最终的 homejs 组件,我们从 frestore 获取图像并在列表视图中显示

import { collection, getDocs } from "firebase/firestore"; 

...

componentDidMount = () => {
    // get Images from Firestore & save To State

    const querySnapshot = await getDocs(collection(db, "users"));
    querySnapshot.forEach((doc) => {
        example.push({
            name: doc.data().name, //Work
            id: doc.data().id,  //Work
            text: doc.data().text,  //Work
            timestamp: doc.data().timestamp,  //Work
            imageRef: doc.data().profilePic // saved in saveToFireStore(): Working
        });
    })
    this.setState({
        posts:example,
        loading: false,
    });
}

现在其他方法 render 和 renderPost 将开始工作,因为用户对象现在有图像

render() {
    return (
        <View style={styles.container}>
            <View style={styles.header}>
                <Text style={styles.headerTitle}>Feed</Text>
            </View>

            <FlatList
                style={styles.feed}
                data={this.state.posts}
                renderItem={({ item }) => this.renderPost(item)}
                keyExtractor={item => item.id}
                showsVerticalScrollIndicator={false}
            ></FlatList>
        </View>
    );
}

显示来自用户对象的图像

renderPost = post => {
    return (
      <Image source = {{uri:post.imageRef}} /> 
    )
}

【讨论】:

  • 感谢您的回复!,但我有另一个名为 PostScreen.js 的组件,在那里我将图像上传到 firebase 并在组件 HomeScreen 中提到了问题,我需要帮助下载图像并将它们显示在屏幕上。所有信息都可用,但没有显示上传后的图像,感谢您的帮助!
  • 您需要将下载链接保存在数据库中以便稍后显示图像
  • 好的...你能举个例子或如何用我的代码做到这一点吗?谢谢!!
  • 获取下载网址包括在内。您使用的是哪个数据库? firebase realtime 还是 firestore?
  • 我正在使用 firestore...在存储中我有一个文件夹,其中包含我上传的所有照片
猜你喜欢
  • 2020-11-06
  • 2018-07-14
  • 2021-02-18
  • 2021-07-12
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
相关资源
最近更新 更多