Làm cách nào để nhận danh sách tất cả các tệp trong Bộ nhớ đám mây trong ứng dụng Firebase?


101

Tôi đang làm việc để tải lên hình ảnh, mọi thứ đều hoạt động tốt, nhưng tôi có 100 hình ảnh và tôi muốn hiển thị tất cả chúng trong của mình View, vì tôi có danh sách đầy đủ các hình ảnh trong một thư mục, tôi không thể tìm thấy bất kỳ API nào cho việc này công việc.


Bạn có thể đăng một giải pháp mã đầy đủ?
ISS

Câu trả lời:


92

Kể từ khi SDK Firebase cho JavaScript phát hành 6.1 , iOS phát hành 6.4Android phiên bản 18.1 đều có một phương pháp để liệt kê tệp.

Các tài liệu là một chút thưa thớt cho đến nay, vì vậy tôi khuyên bạn nên kiểm tra ra câu trả lời Rosario của để biết chi tiết.


Câu trả lời trước, vì phương pháp này đôi khi vẫn có thể hữu ích:

Hiện không có lệnh gọi API nào trong SDK Firebase để liệt kê tất cả các tệp trong thư mục Lưu trữ đám mây từ bên trong ứng dụng. Nếu bạn cần chức năng như vậy, bạn nên lưu trữ siêu dữ liệu của tệp (chẳng hạn như URL tải xuống) ở nơi bạn có thể liệt kê chúng. Các cơ sở dữ liệu căn cứ hỏa lực Realtimeđám mây FireStore là hoàn hảo cho điều này và cho phép bạn cũng dễ dàng chia sẻ các URL với người khác.

Bạn có thể tìm thấy một ví dụ hay (nhưng hơi liên quan) về vấn đề này trong ứng dụng mẫu FriendlyPix của chúng tôi . Mã liên quan cho phiên bản web có ở đây , nhưng cũng có các phiên bản cho iOS và Android.


8
Bạn có định triển khai điều này trên Firebase không?
Pier

55
Nếu tôi cần giữ URL của tất cả các tệp Bộ nhớ của mình trong Cơ sở dữ liệu thời gian thực, thì mục đích của việc phân cấp thư mục trong Bộ nhớ là gì? tất cả các tệp, có tên duy nhất, có thể được lưu trữ trong cùng một cấp, không cần thư mục nào cả !!! bạn thấy đó, đó là một sự mâu thuẫn !!! Về cơ bản, lý do chính đằng sau hệ thống phân cấp thư mục là các truy vấn ký tự đại diện mà không có kiến ​​thức trước về những gì bạn có trong một thư mục, mà bạn không cung cấp một cách hợp lý.
abedfar

7
Firebase Storage được xây dựng trên Google Cloud Storage, thực hiện chính xác những gì bạn nói: nó lưu trữ tất cả các đối tượng trong một danh sách dài. Firebase Storage lập mô hình phân cấp trên đó, được thừa nhận là một phần trừu tượng bị rò rỉ. Các lý do phổ biến để sử dụng thư mục trong Lưu trữ Firebase là để phân tách dữ liệu hợp lý và để tạo các quy tắc bảo mật dựa trên cấu trúc thư mục.
Frank van Puffelen

8
Điều gì xảy ra nếu kết nối người dùng bị mất sau khi tải lên và trước khi lưu downloadUrl vào cơ sở dữ liệu? Làm thế nào chúng tôi phát hiện ra các tệp hiện có trong một thư mục trong trường hợp đó?
Oswaldo

10
Bây giờ thì sao ? Có API trực tiếp nào cho việc này vào năm 2018 không?
Diaz diaz

46

Kể từ tháng 5 năm 2019, phiên bản 6.1.0 của SDK Firebase cho Lưu trữ đám mây hiện hỗ trợ liệt kê tất cả các đối tượng từ một nhóm. Bạn chỉ cần gọi listAll()bằng Reference:

    // Since you mentioned your images are in a folder,
    // we'll create a Reference to that folder:
    var storageRef = firebase.storage().ref("your_folder");


    // Now we get the references of these images
    storageRef.listAll().then(function(result) {
      result.items.forEach(function(imageRef) {
        // And finally display them
        displayImage(imageRef);
      });
    }).catch(function(error) {
      // Handle any errors
    });

    function displayImage(imageRef) {
      imageRef.getDownloadURL().then(function(url) {
        // TODO: Display the image on the UI
      }).catch(function(error) {
        // Handle any errors
      });
    }

Xin lưu ý rằng để sử dụng chức năng này, bạn phải chọn tham gia vào phiên bản 2 của Quy tắc bảo mật , có thể được thực hiện bằng cách thực hiện rules_version = '2';dòng đầu tiên trong quy tắc bảo mật của bạn:

    rules_version = '2';
    service firebase.storage {
      match /b/{bucket}/o {
        match /{allPaths=**} {

Tôi khuyên bạn nên kiểm tra các tài liệu để tham khảo thêm.

Ngoài ra, theo thiết lập , ở Bước 5, tập lệnh này không được phép Node.jsrequire("firebase/app");sẽ không trả về firebase.storage()dưới dạng một hàm. Điều này chỉ đạt được bằng cách sử dụng import * as firebase from 'firebase/app';.


bạn đang sử dụng plugin nào
azheen

@azheen Tôi cho rằng bạn đang sử dụng Flutter. Thật không may, điều này vẫn chưa có sẵn trên flashingfire. Bạn có thể theo dõi nó về vấn đề này
Rosário Pereira Fernandes

33

Kể từ tháng 3 năm 2017: Với việc bổ sung các Chức năng đám mây của Firebase và tích hợp sâu hơn của Firebase với Google Cloud, điều này hiện có thể thực hiện được.

Với Chức năng đám mây, bạn có thể sử dụng gói Google Cloud Node để thực hiện các hoạt động hoành tráng trên Lưu trữ đám mây. Dưới đây là một ví dụ đưa tất cả các URL của tệp vào một mảng từ Cloud Storage. Chức năng này sẽ được kích hoạt mỗi khi nội dung nào đó được lưu vào bộ nhớ đám mây của google.

Lưu ý 1 : Đây là một hoạt động tính toán khá tốn kém, vì nó phải chuyển qua tất cả các tệp trong một nhóm / thư mục.

Lưu ý 2 : Tôi đã viết điều này chỉ để làm ví dụ, không chú ý nhiều chi tiết vào lời hứa, v.v. Chỉ để đưa ra ý tưởng.

const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')();

// let's trigger this function with a file upload to google cloud storage

exports.fileUploaded = functions.storage.object().onChange(event => {

  const object = event.data; // the object that was just uploaded
  const bucket = gcs.bucket(object.bucket);
  const signedUrlConfig = { action: 'read', expires: '03-17-2025' }; // this is a signed url configuration object

  var fileURLs = []; // array to hold all file urls 

  // this is just for the sake of this example. Ideally you should get the path from the object that is uploaded :)
  const folderPath = "a/path/you/want/its/folder/size/calculated";

  bucket.getFiles({ prefix: folderPath }, function(err, files) {
    // files = array of file objects
    // not the contents of these files, we're not downloading the files. 

    files.forEach(function(file) {
      file.getSignedUrl(signedUrlConfig, function(err, fileURL) {
        console.log(fileURL);
        fileURLs.push(fileURL);
      });
    });

  });

});

Tôi hy vọng điều này sẽ cung cấp cho bạn ý tưởng chung. Để biết các ví dụ về chức năng đám mây tốt hơn, hãy xem kho lưu trữ Github của Google với đầy đủ các mẫu Chức năng đám mây cho Firebase . Ngoài ra, hãy xem Tài liệu API Google Cloud Node của họ


35
Đây là quá ngu ngốc mà căn cứ hỏa lực không chỉ cần thêm api này vào sdk căn cứ hỏa lực
Thaina

4
@Thaina Tôi nghĩ rằng nó liên quan đến quy mô. Họ phải nghĩ về không chỉ các ứng dụng nhỏ mà còn cả những ứng dụng khổng lồ. Điều gì sẽ xảy ra nếu một đường dẫn có hàng nghìn tệp. Thao tác này sẽ tiêu tốn rất nhiều công suất tính toán và nó sẽ phải tham chiếu đến cơ sở dữ liệu cho mỗi lệnh gọi có vẻ đơn giản và đơn giản. Tôi càng tham gia sâu hơn vào việc sử dụng firebase trên quy mô lớn, tôi càng hiểu rõ lý do tại sao các thỏa hiệp nhất định được thực hiện.
johnozbay

1
Trong api gcs này, nó cũng có giới hạn và phân trang, sau đó người tiêu dùng API có trách nhiệm phải biết rủi ro và cố gắng chọn phương pháp có thể mở rộng. Nhưng để bảo vệ quá mức nên việc cắt giảm tùy chọn của chúng tôi không phải là một quyết định đúng đắn. Họ có thể tính phí cho việc tải nặng nếu nó thực sự có giá
Thaina

1
đây phải là câu trả lời hàng đầu! Cảm ơn cho những người đứng đầu lên. Hiện tại, cú pháp khác với ví dụ của bạn. Thay vì gửi một cuộc gọi lại dưới dạng một tham số, bạn phải chuỗi một chuỗi .thennhư thế này:this.bucket .getFiles({ prefix: 'path/to/directory' }) .then((arr) => {})
JP Lew

1
@JPLew Bạn được chào đón :) Liên quan đến cú pháp, chúng chỉ trả về một lời hứa nếu cuộc gọi lại bị loại trừ. Vì vậy, nó là an toàn để sử dụng bất cứ điều gì bạn thích. Xem ví dụ tại đây: cloud.google.com/nodejs/docs/reference/storage/1.3.x/…
johnozbay 17/03/18

20

Vì không có ngôn ngữ nào được liệt kê, tôi sẽ trả lời điều này bằng Swift. Chúng tôi thực sự khuyên bạn nên sử dụng Bộ nhớ Firebase và Cơ sở dữ liệu thời gian thực của Firebase cùng nhau để hoàn thành danh sách tải xuống:

Đã chia sẻ:

// Firebase services
var database: FIRDatabase!
var storage: FIRStorage!
...
// Initialize Database, Auth, Storage
database = FIRDatabase.database()
storage = FIRStorage.storage()
...
// Initialize an array for your pictures
var picArray: [UIImage]()

Tải lên:

let fileData = NSData() // get data...
let storageRef = storage.reference().child("myFiles/myFile")
storageRef.putData(fileData).observeStatus(.Success) { (snapshot) in
  // When the image has successfully uploaded, we get it's download URL
  let downloadURL = snapshot.metadata?.downloadURL()?.absoluteString
  // Write the download URL to the Realtime Database
  let dbRef = database.reference().child("myFiles/myFile")
  dbRef.setValue(downloadURL)
}

Tải xuống:

let dbRef = database.reference().child("myFiles")
dbRef.observeEventType(.ChildAdded, withBlock: { (snapshot) in
  // Get download URL from snapshot
  let downloadURL = snapshot.value() as! String
  // Create a storage reference from the URL
  let storageRef = storage.referenceFromURL(downloadURL)
  // Download the data, assuming a max size of 1MB (you can change this as necessary)
  storageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in
    // Create a UIImage, add it to the array
    let pic = UIImage(data: data)
    picArray.append(pic)
  })
})

Để biết thêm thông tin, hãy xem Zero to App: Develop with Firebasemã nguồn liên quan của nó , để biết ví dụ thực tế về cách thực hiện điều này.


3
Nhưng làm thế nào để tôi có được kết quả tương tự với Cloud Firestore?)
Max Kraev

5

Một giải pháp khác có thể là tạo một tệp (tức là list.txt) không có gì bên trong, trong tệp này, bạn có thể đặt siêu dữ liệu tùy chỉnh (đó là Bản đồ <Chuỗi, Chuỗi>) với danh sách tất cả URL của tệp.
Vì vậy, nếu bạn cần downlaod tất cả các tệp trong fodler, trước tiên, bạn tải xuống siêu dữ liệu của tệp list.txt, sau đó bạn lặp lại dữ liệu tùy chỉnh và tải xuống tất cả các tệp có URL trong Bản đồ.


4
Vâng, đây là một cách giải quyết, nhưng không thể xử lý đồng thời ghi vào một list.txt đơn
linquize

5

Tôi cũng gặp phải vấn đề này khi tôi đang thực hiện dự án của mình. Tôi thực sự ước họ cung cấp một phương pháp api kết thúc. Dù sao, đây là cách tôi đã làm: Khi bạn đang tải một hình ảnh lên bộ nhớ Firebase, hãy tạo một Đối tượng và chuyển đối tượng này vào cơ sở dữ liệu Firebase cùng một lúc. Đối tượng này chứa URI tải xuống của hình ảnh.

trailsRef.putFile(file).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            Uri downloadUri = taskSnapshot.getDownloadUrl();
            DatabaseReference myRef = database.getReference().child("trails").child(trail.getUnique_id()).push();
            Image img = new Image(trail.getUnique_id(), downloadUri.toString());
            myRef.setValue(img);
        }
    });

Sau đó, khi bạn muốn tải xuống hình ảnh từ một thư mục, bạn chỉ cần lặp qua các tệp trong thư mục đó. Thư mục này có cùng tên với "thư mục" trong bộ nhớ Firebase, nhưng bạn có thể đặt tên chúng theo cách bạn muốn. Tôi đặt chúng trong chủ đề riêng biệt.

 @Override
protected List<Image> doInBackground(Trail... params) {

    String trialId = params[0].getUnique_id();
    mDatabase = FirebaseDatabase.getInstance().getReference();
    mDatabase.child("trails").child(trialId).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            images = new ArrayList<>();
            Iterator<DataSnapshot> iter = dataSnapshot.getChildren().iterator();
            while (iter.hasNext()) {
                Image img = iter.next().getValue(Image.class);
                images.add(img);
            }
            isFinished = true;
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

Bây giờ tôi có một danh sách các đối tượng chứa URI cho mỗi hình ảnh, tôi có thể làm bất cứ điều gì tôi muốn làm với chúng. Để tải chúng vào imageView, tôi đã tạo một chuỗi khác.

    @Override
protected List<Bitmap> doInBackground(List<Image>... params) {

    List<Bitmap> bitmaps = new ArrayList<>();

    for (int i = 0; i < params[0].size(); i++) {
        try {
            URL url = new URL(params[0].get(i).getImgUrl());
            Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
            bitmaps.add(bmp);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return bitmaps;
}

Thao tác này trả về một danh sách Bitmap, khi nó kết thúc, tôi chỉ cần đính kèm chúng vào ImageView trong hoạt động chính. Các phương thức bên dưới là @Override vì tôi đã tạo các giao diện và lắng nghe để hoàn thành trong các luồng khác.

    @Override
public void processFinishForBitmap(List<Bitmap> bitmaps) {
    List<ImageView> imageViews = new ArrayList<>();
    View v;
    for (int i = 0; i < bitmaps.size(); i++) {
        v = mInflater.inflate(R.layout.gallery_item, mGallery, false);
        imageViews.add((ImageView) v.findViewById(R.id.id_index_gallery_item_image));
        imageViews.get(i).setImageBitmap(bitmaps.get(i));
        mGallery.addView(v);
    }
}

Lưu ý rằng tôi phải đợi Hình ảnh danh sách được trả về trước rồi gọi luồng hoạt động trên Bản đồ bit danh sách. Trong trường hợp này, Hình ảnh chứa URI.

    @Override
public void processFinish(List<Image> results) {
    Log.e(TAG, "get back " + results.size());

    LoadImageFromUrlTask loadImageFromUrlTask =  new LoadImageFromUrlTask();
    loadImageFromUrlTask.delegate = this;
    loadImageFromUrlTask.execute(results);
}

Hy vọng rằng ai đó thấy nó hữu ích. Nó cũng sẽ hoạt động như một đường dây của guild cho tôi trong tương lai.


5

Thêm một cách để thêm hình ảnh vào Cơ sở dữ liệu bằng cách sử dụng Chức năng Đám mây để theo dõi mọi hình ảnh được tải lên và lưu trữ trong Cơ sở dữ liệu.

exports.fileUploaded = functions.storage.object().onChange(event => {

    const object = event.data; // the object that was just uploaded
    const contentType = event.data.contentType; // This is the image Mimme type\

    // Exit if this is triggered on a file that is not an image.
    if (!contentType.startsWith('image/')) {
        console.log('This is not an image.');
        return null;
    }

    // Get the Signed URLs for the thumbnail and original image.
    const config = {
        action: 'read',
        expires: '03-01-2500'
    };

    const bucket = gcs.bucket(event.data.bucket);
    const filePath = event.data.name;
    const file = bucket.file(filePath);

    file.getSignedUrl(config, function(err, fileURL) {
        console.log(fileURL);
        admin.database().ref('images').push({
            src: fileURL
        });
    });
});

Full code tại đây: https://gist.github.com/bossly/fb03686f2cb1699c2717a0359880cf84


5

Đối với nút js, tôi đã sử dụng mã này

const Storage = require('@google-cloud/storage');
const storage = new Storage({projectId: 'PROJECT_ID', keyFilename: 'D:\\keyFileName.json'});
const bucket = storage.bucket('project.appspot.com'); //gs://project.appspot.com
bucket.getFiles().then(results => {
    const files = results[0];
    console.log('Total files:', files.length);
    files.forEach(file => {
      file.download({destination: `D:\\${file}`}).catch(error => console.log('Error: ', error))
    });
}).catch(err => {
    console.error('ERROR:', err);
  });

Bạn vừa cứu được ngày của tôi !!
hugo blanc

4

Bạn có thể liệt kê các tệp trong thư mục lưu trữ firebase bằng phương thức listAll (). Để sử dụng phương pháp này, phải triển khai phiên bản lưu trữ firebase này. 'com.google.firebase: firebase-storage: 18.1.1'

https://firebase.google.com/docs/storage/android/list-files

Hãy nhớ rằng hãy nâng cấp Quy tắc bảo mật lên phiên bản 2.


3

Trên thực tế, điều này có thể thực hiện được nhưng chỉ với API Google Cloud thay vì API từ Firebase. Đó là vì Bộ nhớ Firebase là Nhóm bộ nhớ đám mây của Google , có thể dễ dàng truy cập bằng API đám mây của Google, tuy nhiên bạn cần sử dụng OAuth để xác thực thay vì sử dụng Firebase.


3

Tôi đã đối mặt với cùng một vấn đề, của tôi thậm chí còn phức tạp hơn.

Quản trị viên sẽ tải tệp âm thanh và pdf lên bộ nhớ:

  • tệp audios / season1, season2 ... / class1, class 2 / .mp3

  • sách / tệp .pdf

Ứng dụng Android cần lấy danh sách các thư mục con và tệp.

Giải pháp là bắt sự kiện tải lên trên bộ nhớ và tạo cấu trúc tương tự trên firestore bằng cách sử dụng chức năng đám mây.

Bước 1: Tạo bộ sưu tập 'lưu trữ' theo cách thủ công và tài liệu 'âm thanh / sách' trên firestore

nhập mô tả hình ảnh ở đây

Bước 2: Thiết lập chức năng đám mây

Có thể mất khoảng 15 phút: https://www.youtube.com/watch?v=DYfP-UIKxH0&list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM&index=1

Bước 3: Nắm bắt sự kiện tải lên bằng chức năng đám mây

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);
const path = require('path');

export const onFileUpload = functions.storage.object().onFinalize(async (object) => {
        let filePath = object.name; // File path in the bucket.
        const contentType = object.contentType; // File content type.
        const metageneration = object.metageneration; // Number of times metadata has been generated. New objects have a value of 1.
        if (metageneration !== "1") return;

        // Get the file name.
        const fileName = path.basename(filePath);
        filePath = filePath.substring(0, filePath.length - 1);
        console.log('contentType ' + contentType);
        console.log('fileName ' + fileName);
        console.log('filePath ' + filePath);
        console.log('path.dirname(filePath) ' + path.dirname(filePath));
        filePath = path.dirname(filePath);
        const pathArray = filePath.split("/");
        let ref = '';
        for (const item of pathArray) {
            if (ref.length === 0) {
                ref = item;
            }
            else {
                ref = ref.concat('/sub/').concat(item);
            }
        }

        ref = 'storage/'.concat(ref).concat('/sub')
        admin.firestore().collection(ref).doc(fileName).create({})
                .then(result => {console.log('onFileUpload:updated')})
                .catch(error => {
                    console.log(error);
                });
    });

Bước 4: Truy xuất danh sách các thư mục / tệp trên ứng dụng Android bằng firestore

private static final String STORAGE_DOC = "storage/";
    public static void getMediaCollection(String path, OnCompleteListener onCompleteListener) {
        String[] pathArray = path.split("/");
        String doc = null;
        for (String item : pathArray) {
            if (TextUtils.isEmpty(doc)) doc = STORAGE_DOC.concat(item);
            else doc = doc.concat("/sub/").concat(item);
        }
        doc = doc.concat("/sub");

        getFirestore().collection(doc).get().addOnCompleteListener(onCompleteListener);
    }

Bước 5: Lấy url tải xuống

public static void downloadMediaFile(String path, OnCompleteListener<Uri> onCompleteListener) {
        getStorage().getReference().child(path).getDownloadUrl().addOnCompleteListener(onCompleteListener);
    }

Ghi chú

Chúng tôi phải đặt bộ sưu tập "phụ" cho từng mục vì firestore không hỗ trợ lấy danh sách bộ sưu tập.

Tôi đã mất 3 ngày để tìm ra giải pháp, hy vọng sẽ mất tối đa 3 giờ.

Chúc mừng.


Chính xác là cùng một kịch bản mà tôi đang làm. Có ai có thể gửi cho tôi mã rung không? bởi vì tôi chỉ có thể tải lên hàng loạt tệp, không tải xuống.
Mahesh Peri

Flutter SDK (ngôn ngữ phi tiêu)
Mahesh Peri

1
cloud firestore vẫn chưa hỗ trợ firebase.google.com/docs/firestore . Cách tiếp cận nhanh là viết API bằng cách sử dụng chức năng đám mây, sau đó truy cập các API này thông qua chế độ nghỉ ngơi như bình thường. Nó có thể mất vài giờ để làm quen với chức năng điện toán đám mây, các video đào tạo là khá dễ dàng để nuốt: D youtube.com/...
thanhbinh84

3

Mở rộng câu trả lời của Rosário Pereira Fernandes , cho một giải pháp JavaScript:

  1. Cài đặt firebase trên máy của bạn
npm install -g firebase-tools

  1. Trên firebase, init được đặt JavaScriptlàm ngôn ngữ mặc định
  2. Trên thư mục gốc của dự án đã tạo, thực hiện cài đặt npm
   npm install --save firebase
   npm install @google-cloud/storage
   npm install @google-cloud/firestore
   ... <any other dependency needed>
  1. Thêm các phần phụ thuộc không mặc định vào dự án của bạn như
    "firebase": "^6.3.3",
    "@google-cloud/storage": "^3.0.3"

functions / package.json

{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "lint": "eslint .",
    "serve": "firebase serve --only functions",
    "shell": "firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "engines": {
    "node": "10"
  },
  "dependencies": {
    "@google-cloud/storage": "^3.0.3",
    "firebase": "^6.3.3",
    "firebase-admin": "^8.0.0",
    "firebase-functions": "^3.1.0"
  },
  "devDependencies": {
    "eslint": "^5.12.0",
    "eslint-plugin-promise": "^4.0.1",
    "firebase-functions-test": "^0.1.6"
  },
  "private": true
}

  1. Tạo loại listAllchức năng

index.js

var serviceAccount = require("./key.json");
const functions = require('firebase-functions');

const images = require('./images.js');

var admin = require("firebase-admin");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://<my_project>.firebaseio.com"
});

const bucket = admin.storage().bucket('<my_bucket>.appspot.com')

exports.getImages = functions.https.onRequest((request, response) => {
    images.getImages(bucket)
        .then(urls => response.status(200).send({ data: { urls } }))
        .catch(err => console.error(err));
})

images.js

module.exports = {
    getImages
}

const query = {
    directory: 'images'
};

function getImages(bucket) {
    return bucket.getFiles(query)
        .then(response => getUrls(response))
        .catch(err => console.error(err));
}

function getUrls(response) {
    const promises = []
    response.forEach( files => {
        files.forEach (file => {
            promises.push(getSignedUrl(file));
        });
    });
    return Promise.all(promises).then(result => getParsedUrls(result));
}

function getSignedUrl(file) {
    return file.getSignedUrl({
        action: 'read',
        expires: '09-01-2019'
    })
}

function getParsedUrls(result) {
    return JSON.stringify(result.map(mediaLink => createMedia(mediaLink)));
}

function createMedia(mediaLink) {
    const reference = {};
    reference.mediaLink = mediaLink[0];
    return reference;
}

  1. Thực thi firebase deploytải lên chức năng đám mây của bạn
  2. Gọi chức năng tùy chỉnh của bạn từ ứng dụng của bạn

build.gradle

dependencies {
...
  implementation 'com.google.firebase:firebase-functions:18.1.0'
...
}

lớp kotlin

  private val functions = FirebaseFunctions.getInstance()
  val cloudFunction = functions.getHttpsCallable("getImages")
  cloudFunction.call().addOnSuccessListener {...}

Về việc phát triển thêm tính năng này, tôi đã gặp phải một số vấn đề có thể tìm thấy ở đây .


2

Để làm điều này với JS

Bạn có thể nối chúng trực tiếp vào vùng chứa div của mình hoặc bạn có thể đẩy chúng vào một mảng. Phần dưới đây cho bạn biết cách nối chúng vào div của bạn.

1) Khi bạn lưu trữ hình ảnh của mình trong bộ nhớ, hãy tạo tham chiếu đến hình ảnh trong cơ sở dữ liệu firebase của bạn với cấu trúc sau

/images/(imageName){
   description: "" , 
   imageSrc : (imageSource) 
}

2) Khi bạn tải tài liệu, bạn kéo tất cả các URL nguồn hình ảnh của bạn từ cơ sở dữ liệu thay vì lưu trữ với mã sau

$(document).ready(function(){

var query = firebase.database().ref('images/').orderByKey();
query.once("value").then(function(snapshot){

    snapshot.forEach(function(childSnapshot){

        var imageName = childSnapshot.key;
        var childData = childSnapshot.val();
        var imageSource = childData.url;

        $('#imageGallery').append("<div><img src='"+imageSource+"'/></div>");

    })
})
});

2

Bạn có thể sử dụng mã sau. Ở đây tôi đang tải hình ảnh lên bộ lưu trữ firebase và sau đó tôi đang lưu trữ url tải xuống hình ảnh vào cơ sở dữ liệu firebase.

//getting the storage reference
            StorageReference sRef = storageReference.child(Constants.STORAGE_PATH_UPLOADS + System.currentTimeMillis() + "." + getFileExtension(filePath));

            //adding the file to reference 
            sRef.putFile(filePath)
                    .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                            //dismissing the progress dialog
                            progressDialog.dismiss();

                            //displaying success toast 
                            Toast.makeText(getApplicationContext(), "File Uploaded ", Toast.LENGTH_LONG).show();

                            //creating the upload object to store uploaded image details 
                            Upload upload = new Upload(editTextName.getText().toString().trim(), taskSnapshot.getDownloadUrl().toString());

                            //adding an upload to firebase database 
                            String uploadId = mDatabase.push().getKey();
                            mDatabase.child(uploadId).setValue(upload);
                        }
                    })
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception exception) {
                            progressDialog.dismiss();
                            Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_LONG).show();
                        }
                    })
                    .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                            //displaying the upload progress 
                            double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
                            progressDialog.setMessage("Uploaded " + ((int) progress) + "%...");
                        }
                    });

Bây giờ để tìm nạp tất cả các hình ảnh được lưu trữ trong cơ sở dữ liệu firebase, bạn có thể sử dụng

//adding an event listener to fetch values
        mDatabase.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot snapshot) {
                //dismissing the progress dialog 
                progressDialog.dismiss();

                //iterating through all the values in database
                for (DataSnapshot postSnapshot : snapshot.getChildren()) {
                    Upload upload = postSnapshot.getValue(Upload.class);
                    uploads.add(upload);
                }
                //creating adapter
                adapter = new MyAdapter(getApplicationContext(), uploads);

                //adding adapter to recyclerview
                recyclerView.setAdapter(adapter);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                progressDialog.dismiss();
            }
        });

Để biết thêm chi tiết, bạn có thể xem bài đăng của tôi Ví dụ về lưu trữ Firebase .


Tôi đi theo ví dụ của bạn trong liên kết, nhưng những hình ảnh không được hiển thị từ căn cứ hỏa lực trong RecyclerView
Wolfiebae

1

Vì vậy, tôi có một dự án yêu cầu tải xuống nội dung từ bộ lưu trữ firebase, vì vậy tôi phải tự giải quyết vấn đề này. Đây là Cách:

1- Đầu tiên, hãy tạo một dữ liệu mô hình chẳng hạn class Choice{}, Trong lớp đó định nghĩa một biến Chuỗi được gọi là Tên hình ảnh nên nó sẽ như thế

class Choice {
    .....
    String imageName;
}

2- từ cơ sở dữ liệu cơ sở dữ liệu / cơ sở dữ liệu firebase, đi và mã hóa tên hình ảnh cho các đối tượng, vì vậy nếu bạn có tên hình ảnh là Apple.png, hãy tạo đối tượng

Choice myChoice = new Choice(...,....,"Apple.png");

3- Bây giờ, hãy lấy liên kết cho các nội dung trong bộ nhớ firebase của bạn, nó sẽ giống như vậy

gs://your-project-name.appspot.com/

Giống như cái này

4- cuối cùng, khởi tạo tham chiếu bộ nhớ firebase của bạn và bắt đầu tải các tệp theo một vòng lặp như vậy

storageRef = storage.getReferenceFromUrl(firebaseRefURL).child(imagePath);

File localFile = File.createTempFile("images", "png");
storageRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {

@Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
    //Dismiss Progress Dialog\\
}

5- đó là nó


1
#In Python

import firebase_admin
from firebase_admin import credentials
from firebase_admin import storage
import datetime
import urllib.request


def image_download(url, name_img) :
    urllib.request.urlretrieve(url, name_img)

cred = credentials.Certificate("credentials.json")

# Initialize the app with a service account, granting admin privileges
app = firebase_admin.initialize_app(cred, {
    'storageBucket': 'YOURSTORAGEBUCKETNAME.appspot.com',
})
url_img = "gs://YOURSTORAGEBUCKETNAME.appspot.com/"
bucket_1 = storage.bucket(app=app)
image_urls = []

for blob in bucket_1.list_blobs():
    name = str(blob.name)
    #print(name)
    blob_img = bucket_1.blob(name)
    X_url = blob_img.generate_signed_url(datetime.timedelta(seconds = 300), method='GET')
    #print(X_url)
    image_urls.append(X_url)


PATH = ['Where you want to save the image']
for path in PATH:
    i = 1
    for url  in image_urls:
        name_img = str(path + "image"+str(i)+".jpg")
        image_download(url, name_img)
        i+=1

Không cần API, bạn chỉ cần một lớp Python đơn giản và từ khóa blob
Milan Hazra

0

Tôi đang sử dụng AngularFirevà sử dụng phần sau để có được tất cảdownloadURL

getPhotos(id: string): Observable<string[]> {
    const ref = this.storage.ref(`photos/${id}`)
    return ref.listAll().pipe(switchMap(list => {
      const calls: Promise<string>[] = [];
      list.items.forEach(item => calls.push(item.getDownloadURL()))
      return Promise.all(calls)
    }));
}

-1

Đối với Android, cách tốt nhất là sử dụng FirebaseUI và Glide.

Bạn cần thêm nó vào gradle / ứng dụng của mình để có được thư viện. Lưu ý rằng nó đã có tính năng Glide trên đó!

implementation 'com.firebaseui:firebase-ui-storage:4.1.0'

Và sau đó sử dụng mã của bạn

// Reference to an image file in Cloud Storage
StorageReference storageReference = FirebaseStorage.getInstance().getReference();

// ImageView in your Activity
ImageView imageView = findViewById(R.id.imageView);

// Download directly from StorageReference using Glide
// (See MyAppGlideModule for Loader registration)
GlideApp.with(this /* context */)
        .load(storageReference)
        .into(imageView);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.