Как загрузить несколько URL-адресов изображений из хранилища Firebase? - PullRequest
0 голосов
/ 10 октября 2019

Usecase:

Пользователь выбирает несколько снимков с камеры и добавляет их в свой пост. Они вводят описание и заголовок, а затем выбирают для публикации. Их сообщение появляется в их профиле пользователя с прикрепленными выбранными ими изображениями.

Проблема:

Я создаю имиджевое приложение для блога с Ionic 4, AngularFire2. Моя цель - загрузить изображения пользователей в хранилище Firebase и загрузить каждый URL-адрес изображения для ссылки в базе данных Firestore.

Я могу загрузить несколько изображений в хранилище Firebase, однако я хочу загрузить каждое из них. URL изображения. Пока я могу загрузить только один 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);
        })
    })
  })
}

Моя база данных пожарного депо в настоящее время выглядит следующим образом

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 голосов
/ 10 октября 2019

Я нашел что-то подходящее для вашей ситуации, но для Android

Источник: Firebase Storage загрузить несколько фотографий 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();}


        }
    }

}
...