如何从Firebase存储下载多个图片网址?

时间:2019-10-10 14:13:09

标签: angular typescript firebase ionic-framework firebase-storage

用例:

用户从相机胶卷中选择多张图像,并将它们添加到他们的帖子中。他们键入描述和标题,然后选择发布。他们的帖子显示在用户个人资料中,并附有他们选择的图像。

问题:

我正在使用Ionic 4,AngularFire2创建一个图像博客应用程序。 我的目标是将用户图像上传到Firebase存储,并下载每个图像URL以在Firestore数据库中进行引用。

我可以将多个图像上传到Firebase存储,但是我想下载每个图像URL。到目前为止,我只能下载一个图片网址。我是Ionic / AngularFire的新手,我不知道要循环播放什么或应该在何处循环获取数组中的图像URL。

打字稿:

async uploadImageToFirebase(image){
let image_src = this.webview.convertFileSrc(image);
let randomId = Math.random().toString(36).substr(2, 5);

//uploads img to firebase storage
this.firebaseService.uploadImage(image_src, randomId)
  .then(photoURL => {
     this.image = [ photoURL ] 
     loading.dismiss();
     toast.present();
  }, err => {
     console.log(err);
  })

服务:

encodeImageUri(imageUri, callback) {
  var c = document.createElement('canvas');
  var ctx = c.getContext("2d");
  var img = new Image();
  img.onload = function () {
    var aux:any = this;
    c.width = aux.width;
    c.height = aux.height;
    ctx.drawImage(img, 0, 0);
    var dataURL = c.toDataURL("image/jpeg");
    callback(dataURL);
  };
  img.src = imageUri;
};

uploadImage(imageURI, randomId){
  return new Promise<any>((resolve, reject) => { 
    let storageRef = firebase.storage().ref();
    let imageRef  = 
      storageRef.child('image').child(randomId);
    this.encodeImageUri(imageURI, function(image64){
      imageRef.putString(image64, 'data_url')
        .then(snapshot => {  
           snapshot.ref.getDownloadURL()
             .then(res => resolve(res))
        }, err => {
          reject(err);
        })
    })
  })
}

我的firestore数据库当前如下所示

posts : {
  Title : this is a title,
  Description: this is a description,
  image:
    [ 0 ] "https://firebasestorage.googleapis.com/v0/b/imagepost-1962c.appspot.com/o/image%2Fbak95?alt=media&token=58eb6037-4253-4dcc-b35b-8d58ddsdffss"
}

但是我希望它看起来像

posts : {
  Title : this is a title,
  Description: this is a description,
  image:
    [ 0 ] "https://firebasestorage.googleapis.com/v0/b/imagepost-1962c.appspot.com/o/image%2Fbak95?alt=media&token=58eb6037-4253-4dcc-b35b-8d58ddsdffss"
    [ 1 ] "another image url"
    [ 2 ] "another image url"
}

1 个答案:

答案 0 :(得分:0)

我发现了与您给定情况相关的内容,但对于Android

来源:Firebase Storage download multiple photos Urls

public static final String TAG = "eyaldebug";
public static PathGenerator pathGenerator;
public static ArrayList<String>photoURLs;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_photopackges);

    //Initialize the whole process

    photoURLs = new ArrayList<>();

    pathGenerator = new PathGenerator();

    new UrlProducer(pathGenerator);


}


/**
 * This class contains the GeneratePaths method,which responsible
 * of making new paths.
 * Also we have a simple set - get methods of the booleans.
 */

class PathGenerator {
    //start photo number
    int photoNumber = 0;
    //boolean that indicates if the path has been used already or not.
    boolean pathIsTaken = false;
    //our storage path.
    String path;

    /**
     * This method will generate a new path.
     * while path is taken , wait because we didn't use it yet.
     *
     * @param photoNumber
     */

    public synchronized String generatePath(int photoNumber) {

        while (pathIsTaken)
        {
            try {wait();} catch (Exception e) {}
        }
        this.photoNumber = photoNumber;
        path = "test/" + String.valueOf(photoNumber) + ".jpg";
        pathIsTaken = true;
        Log.e("eyaldebug", "path is :  " + path);
        return path;
    }

    /**
     * Simple set method.
     * @param value
     */

    public synchronized void setPathisSet(boolean value)
    {
        this.pathIsTaken = value;
    }

    /**
     * Unfreeze the thread, we call this method after onSucsess.
     */

    public synchronized void unfreeze( )
    {
        notifyAll();
    }

}


/**
 * Our URLProducer calls will take the paths,and will
 * send HTTP request to the storage that we'll get a
 * download URL returned.
 * later we'll be using Glide\Picasso to display those images.
 */

class UrlProducer implements Runnable {

    PathGenerator mPathGenerator;

    //initialize a String type ArrayList which will contain our URLS.
    public  ArrayList<String>photoURLs = new ArrayList<>();

    //constructor that will be called in the activity
    public UrlProducer(PathGenerator mPathGenerator) {
        this.mPathGenerator = mPathGenerator;

        Thread b = new Thread(this, "UrlProducer");
        b.start();
    }

    /**
     * Here we a simple download URL method using FirebaseStorage.
     * for the documentation for FirebaseStoarge download go to :
     *
     * https://firebase.google.com/docs/storage/android/download-files
     *
     * IF the task was successful we UNfreeze the threads so it will
     * keep sending us new URLS.
     * IF the onFailure was called the stroage is must likely empty and
     * we should stop trying to get new photos.
     */

    @Override
    public void run() {


        int photoNumber =0 ;

        while (true) {


            photoNumber ++;

            try {
                FirebaseStorage storage = FirebaseStorage.getInstance();
                StorageReference ref = storage.getReference();


                ref.child(pathGenerator.generatePath(photoNumber)).getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                    @Override
                    public void onSuccess(Uri uri) {

                        Log.e(TAG, "Success! " + uri);

                        //add the URL into the ArrayList
                        photoURLs.add(String.valueOf(uri));

                       //tell the generate method that the path has been used.
                        pathGenerator.setPathisSet(false);

                        //Unfreeze the thread so it will continue generate new paths.
                        pathGenerator.unfreeze();

                    }
                }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {

                        //When onFailure is called shutdown,and output the given ArrayList.

                        Log.e(TAG,"onFailure was called , storage is empty!");
                        Log.e(TAG,"----------------------------------------");
                        for(String singleUrl :photoURLs)
                        {
                            Log.e(TAG,""+singleUrl)   ;
                        }
                    }
                });


            }catch (Exception e){e.printStackTrace();}


        }
    }

}