【问题标题】:Setting image source to Firebase Storage URL with React Native使用 React Native 将图像源设置为 Firebase 存储 URL
【发布时间】:2018-01-09 02:33:11
【问题描述】:

所以我试图将图像源设置为从 Firebase 存储返回的下载 url...问题是它没有显示图像,但控制台和下载 url 都显示正确的存储 url 到图片。 .. 这是我目前拥有的代码:

this.state = {
      itemDataSource: ds,
      modalVisible: false,
      user: undefined,
      imgSource: undefined,
    };

  getTrucks(truckRef, storageRef) {
    truckRef.once('value', (snap) => {
      console.log(snap.val());
      // console.log(snap.key);
      let trucks = [];
      snap.forEach((trucksSnap) => {
        console.log(trucksSnap.key);
        uid = trucksSnap.key;
        this.setState({user: uid});
        trucksSnap.forEach((truckSnap) => {
          console.log(truckSnap.key);
          console.log(truckSnap.val());
          let truck = truckSnap.val();
          trucks.push({
            uid: uid,
            name: truck.name,
            food: truck.foodType,
            desc: truck.description,
            menu: truck.menu,
            phone: truck.phone, 
          });
        });
      });
      console.log(trucks);
      this.setState({
        itemDataSource: this.state.itemDataSource.cloneWithRows(trucks)
      });
    });
  }

getPics(storageRef) {
        setTimeout(() => {
        storageRef.ref('trucks/' + this.state.user + '/pic-1').getDownloadURL()
          .then((url) => {
            console.log(url);
            this.setState({imgSource: url});
          });
        }, 3000);
      }

<Image
  source={{uri: this.state.imgSource}} 
  style={styles.iosCardImage}/>

图像在渲染函数中,没有图像显示在屏幕上,但控制台将其显示为实际的 url,我可以单击并查看图像

我确实查看了其他示例问题,但没有发布或检查为正确的实际工作答案。

React-Native: Download Image from Firebase Storage

Load and return an image from Firebase database/storage in React Native

React Native 的版本是 0.45.1,而 Firebase 的版本是 4.1.3

有人可以帮我正确设置源标签吗? 谢谢

【问题讨论】:

    标签: firebase react-native firebase-storage


    【解决方案1】:

    我遇到了与此类似的问题,我的下载 URL 正确,但图片未显示。 由于样式问题,很可能没有显示图像。 iosCardImage 中有什么?如果您还没有,请尝试定义 widthheight。尝试做:

    <Image
     source={{uri: this.state.imgSource}} 
     style={{ height: 200 }}/>
    

    并查看图像是否显示。

    【讨论】:

    • @marcST...这是我的卡片样式:`height: 80, marginLeft: 8, marginRight: 10, marginTop: 10, resizeMode: 'contain', width: 90, 当我为图像设置背景颜色,它显示一个图像轮廓框。不确定这里发生了什么。我昨晚确实有一个 shouldComponentUpdate() 来调用,以防数据延迟进入并且它仍然在做同样的事情。 react native 是否可能在 z 轴上具有可能导致此问题的样式?
    【解决方案2】:

    为了供其他人将来参考,这里是执行此操作的方法... 但是,正如@marcST 提到的那样,您必须使用 React Natives 内联样式或外部样式表在样式中设置高度和宽度。这是您可以完成此操作的 2 种方法,我发布此方法是因为 StackOverflow 上没有关于如何在 React Native 中正确执行此操作的有效答案

    第一种方式: 所以你需要注意一些关于这种方式的事情。

    1. 此时您可以使用 .push() 将数据添加到您的 Firebase 数据库/存储中
    2. 您首先需要将状态设置为undefined || null || ''
    3. 您应该使用shouldComponentMount(),因为在组件安装到屏幕之前,某些数据不会进入
    4. 你需要JSON.stringify从你的getDownloadURL()返回的URL

    this.state = { itemDataSource: ds, 模态可见:假, 用户:未定义, imgSource:未定义, };

      shouldComponentUpdate(nextState) {
        return nextState.imgSource !== this.state.imgSource;
      }
    
      getTrucks(truckRef, storageRef) {
        truckRef.once('value', (snap) => {
          console.log(snap.val());
          // console.log(snap.key);
          let trucks = [];
          snap.forEach((trucksSnap) => {
            console.log(trucksSnap.key);
            uid = trucksSnap.key;
            this.setState({user: uid});
            trucksSnap.forEach((truckSnap) => {
              console.log(truckSnap.key);
              console.log(truckSnap.val());
              let truck = truckSnap.val();
              trucks.push({
                uid: uid,
                name: truck.name,
                food: truck.foodType,
                desc: truck.description,
                menu: truck.menu,
                phone: truck.phone, 
              });
            });
          });
          console.log(trucks);
          this.setState({
            itemDataSource: this.state.itemDataSource.cloneWithRows(trucks)
          });
        });
      }
    
    getPics(storageRef) {
            setTimeout(() => {
            storageRef.ref('trucks/' + this.state.user + '/pic-1').getDownloadURL()
              .then((url) => {
                console.log(url);
                let imgURL = JSON.stringify(url)
                this.setState({imgSource: imgURL});
              });
            }, 3000);
          }
    
    <Image
      source={{uri: this.state.imgSource}} 
      style={styles.iosCardImage}/>
    

    第二种方式:

    1. 使用 .set() 将数据添加到您的 Firebase 数据库中
    2. 我使用 .set() 添加加载时返回的 URL,以保存到我的 Firebase 数据库中的“图像”文件夹下...见下图代码
    3. 当您将下载 URL 放入数据库时​​,您无需多次运行 snapshot.forEach 即可访问您的数据,因为您通过每次推送时推送 Firebase 设置来绕过唯一 ID 设置。
    4. 当您使用图像 URL 从数据库中提取数据时,您不需要 JSON.stringify 将它们添加为图像 URI。
    5. 您无需设置状态即可将 URL 添加为 URI 源
    6. 您现在可以像访问普通 JSON 对象一样使用点符号来访问您的数据

    这是我解决这个问题的组件代码...

      getTrucks(truckRef) {
        truckRef.on('value', (snap) => {
          console.log(snap.val());
          let truck = snap.val();
          let trucks = [];
          snap.forEach((truck) => {
            trucks.push({
              uid: truck.key,
              name: truck.val().data.name,
              food: truck.val().data.foodType,
              desc: truck.val().data.description,
              menu: truck.val().data.menu,
              phone: truck.val().data.phone,
              pic1: truck.val().mainImage.pic1,
              pic2: truck.val().image2.pic2,
              pic3: truck.val().image3.pic3,
              pic4: truck.val().image4.pic4,
              pic5: truck.val().image5.pic5,
              pic6: truck.val().image6.pic6
            });
            console.log(trucks);
          });
          this.setState({
            itemDataSource: this.state.itemDataSource.cloneWithRows(trucks),
          });
        });
      }
    
      <Image
       source={{uri: truck.pic1}} 
       style={styles.iosCardImage}/>
    

    这是我说的set方法的数据库代码

    let url = task.snapshot.downloadURL;
    trucksRef.child(user).child('mainImage').set({pic1: url});
    
     trucksRef.child(firebaseUser.uid).child('data').set({
        name: $('#name').val(),
        foodType: $('#food').val(),
        description: $('#description').val(),
        address: $('#address').val(),
        city: $('#city').val(),
        zip: $('#zip').val(),
        phone: $('#phone').val(),
        menu: $('#menu').val(),
        });
    

    如果您使用.set() 而不是.push(),则参考数据库中发生的情况的图片

    如果您有其他问题,请告诉我

    【讨论】:

      【解决方案3】:

      我解决了这个问题... 路径/android/app/src/main/AndroidManifest.xml

      android:largeHeap="true

      <application
        android:name=".MainApplication"
        android:label="@string/app_name"
        android:icon="@mipmap/ic_launcher"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:allowBackup="false"
        android:largeHeap="true"
        android:theme="@style/AppTheme">
      

      我经常将 android:largeHeap="true" 视为一种公认的解决方案,但这不是正确的解决方案。我们只是扩大了堆(如果目标设备有能力这样做),这意味着您的应用程序可能会工作更长时间,但最终可能会失败。

      【讨论】:

        猜你喜欢
        • 2020-03-17
        • 2020-03-06
        • 1970-01-01
        • 1970-01-01
        • 2017-01-16
        • 2020-03-23
        • 2018-12-25
        • 1970-01-01
        • 2016-11-20
        相关资源
        最近更新 更多