【问题标题】:Function that returns download URL from Firebase storage从 Firebase 存储返回下载 URL 的函数
【发布时间】:2016-11-26 04:25:34
【问题描述】:

我正在编写此函数以在我的 Angular 应用程序中使用来评估 ng-repeat 列表中的 ng-src。我需要使调用同步,以便每次调用函数时值都是正确的。问题是:

为什么这段代码会返回一个值:

var storage = firebase.storage();
var returnVal; //causes sync issues
var getImageUrl = function (time) {
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) {
        returnVal = url;
    });
    return returnVal;
};

但这不起作用:

var storage = firebase.storage();
var getImageUrl = function (time) {
    var returnVal; //so that this is specific to the function
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) {
        returnVal = url; //I simply want to return the value of 'url'
    });
    return returnVal;
};

有什么想法可以让 getImageUrl() 函数从 .then 返回 url?

这是文档链接:https://firebase.google.com/docs/storage/web/download-files

最后我会把它变成一个 $scope 函数来使用类似于这个:

<div ng-repeat="message in messages">
    <img ng-src="{{ getImageUrl(message.time) }}">
</div>

【问题讨论】:

标签: javascript angularjs firebase firebase-storage


【解决方案1】:

您可以在 firebase-storage

中使用ajax 作为下载文件
const link = linkYourFirebaseImage + folderStoreImage + '2F' + fileName;
// example: const link = https://firebasestorage.googleapis.com/v0/b/myApp.appspot.com/o/myDir%2F1608378322792.PNG;


function downloadImage(fileName, defaultImage) {
  if (fileName.length == 0) return defaultImage;

  let imageUrl;
  $.ajax({
    type: "GET",
    async: false,
    url: link ,
    success: function (response) {
      imageUrl = `${link}alt=media&token=${response.downloadTokens}`;
    },
  });

  return imageUrl;
}

如何使用?

const myImage = downloadImage('myPath.png', '../default.png');

【讨论】:

    【解决方案2】:

    theblindprophet 的回答很好地解释了为什么您当前的代码不起作用以及一个可行的解决方案。

    作为替代方案,您可以简单地返回 getDownloadURL() 返回的所谓承诺。我还没有测试过,但希望 Angular 会自动获得承诺。

    var storage = firebase.storage();
    var getImageUrl = function (time) {
        return storage.ref('images/' + time + '.jpg').getDownloadURL();
    };
    

    您只需在 HTML 中保留:

    <div ng-repeat="message in messages">
        <img ng-src="{{ getImageUrl(message.time) }}">
    </div>
    

    【讨论】:

      【解决方案3】:

      您的函数的任何变体都不会返回不是null 或undefined 的值。您正在执行一个异步调用,在继续执行它下面的代码之前不会等待结果。例如:

      var storage = firebase.storage();
      // Execute (1)
      var getImageUrl = function (time) {
          // Execute (2)
          var returnVal;
          // Execute (3)
          storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) {
              // Execute (unknown)
              returnVal = url;
          });
          // Execute (4)
          return returnVal;
      };
      // Execute (unknown times)
      

      您不知道异步调用何时返回数据,但它总是在return returnVal; 之后,因此returnVal 为空。

      我推荐这个:

      $scope.images = [];
      $scope.messages = { // whatever };
      for (m in $scope.messages) {
          storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) {
              // Might need $scope.$apply(function() {} ) surrounding
              $scope.images.push(url);
          });
      }
      

      那么在你看来:

      <div ng-repeat="image in images">
          <img ng-src="{{ image }}">
      </div>  
      

      所有这些加载的时间取决于$scope.messages 的大小。如果数量很大,我建议您更改数据结构,这样您就不必多次调用数据库。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-09
        • 2019-09-29
        • 1970-01-01
        • 2021-04-03
        • 1970-01-01
        • 2021-12-06
        • 2020-04-26
        • 2017-06-07
        相关资源
        最近更新 更多