I want to use Firebase (FirebaseStorage, Realtimedatabase) to display images on Android.

Asked 2 years ago, Updated 2 years ago, 88 views

teratail posts the same question.

On Android, we are developing an app that uses Firebase (FirebaseStorage, Realtimedatabase) to display images, text, etc.
Text data is kept in the Realtimedatabase and images downloadURL is kept in the Realtimedatabase, from which the image is retrieved from FirebaseStorage.

However, when implemented, the image disappears and the image appears where the text should be displayed, causing unintended behavior.
The probable cause is that FirebaseStorage, which is used to retrieve images, and Realtimedatabase, which is used to retrieve other images, are both working asynchronously as shown below.

For example, if the fourth loop of for (DataSnapshotds...) on the realtimeDatabase side was image 1, and the Realtimedatabase was going up to the seventh loop when the acquisition of the image data (FireStorage side) was completed, the messageDataBean on the fourth loop would be updated.

To prevent this, for example, after you have finished retrieving the image you started retrieving in the fourth loop, you need to install it in the image field of the fourth loop List (messageDataBean) and the image you tried to retrieve in the eighth loop List.

Also, I tried to keep the order of image acquisition by locking each loop by referring to the page below, but it didn't work.

Java Exclusive Control (Lock) Class Summary - Qiita

page called java.concurrent.locks.Lock,Condition in

DatabaseReference ref=;
Bitmap imgBitmap;
ArrayList<MessageDataBean>messageDataBean=newArrayList<MessageDataBean>();;
// Read DB (Realtimedatabase except image)
ref.addValueEventListener(){
    @ Override
    public void onDataChange(@NonNullDataSnapshotdataSnapshot){
        for (DataSnapshot: dataSnapshot.getChildren()) {
            String txtData1;
            String txtData2;
            String msgType=ds.child("type").getValue();

            For if(msgType.equals("txt"){// text:
                txtData1 = ds.child("txt1").getValue();
                txtData2=ds.child("txt2").getValue();

            } else if(msgType.equals("img")) {// For Images
                // Image Download URL
                String downloadURL = String.valueOf(ds.child("img_dl_url").getValue());
                StorageReference images=FirebaseStorage.getInstance().getReferenceFromUrl(downloadURL);
                // Specify the maximum download size
                final long ONE_MEGABYTE = 1024*1024;

                images.getBytes(ONE_MEGABYTE).addOnSuccessListener(newOnSuccessListener<byte[]>(){
                    @ Override
                    public void onSuccess(byte[]bytes) {
                        // Image Download Successful
                        imgBitmap = OtherUtils.createBitmap (bytes, 1024, 1024);
                    }
                }).addOnFailureListener(newOnFailureListener(){
                    @ Override
                    public void onFailure(@NonNullException exception) {
                        // Image download failure
                    }
                });
            }

            MessageDataBean messageDataBean=new MessageDataBean(
                txtData1,
                txtData2,
                imgBitmap,
            );

            messageDataBeanList.add(messageDataBean);
            show(messageDataBeanList);// Display Update Process  
        }
    }
    @ Override
    public void onCancelled(@NonNullDatabaseErrordatabaseError) {
    }
});

java android firebase android-asynctask

2022-09-30 11:11

1 Answers

Hello, nice to meet you.I saw the code.
Let me give you a point of concern.

    First of all, I think there is a problem with the part of the
  • for loop that reads the image.There is no guarantee that onSuccess will be referred to as a replacement for messageDataBean immediately (because of the time-consuming process, it will be referred to as onSuccess if the application desperately needs a bitmap replaced by ArrayList).However, in this flow, reflection on ui is difficult because it needs to be synchronized.I recommend you to consider other methods
  • At this point, it would be better to read directly from the URL information to the view in a library such as Glide.
    https://qiita.com/hotchemi/items/375d63261f2eed2b18e1

  • I couldn't guess how to display it on the screen from the code you gave me.Depending on the view you use on Android, the implementation method often follows a certain form.FriendlyChat in codelab deals with real-time database processing and image display from Storage, so it may be helpful.
    https://codelabs.developers.google.com/codelabs/firebase-android/ #1
    https://github.com/firebase/friendlychat-android

  • In this case, you don't have to worry about exclusive control

At this point, it would be better to read directly from the URL information to the view in a library such as Glide instead of loading the image.
https://qiita.com/hotchemi/items/375d63261f2eed2b18e1

I couldn't guess how to display it on the screen from the code you gave me.Depending on the view you use on Android, the implementation method often follows a certain form.FriendlyChat in codelab deals with real-time database processing and image display from Storage, so it may be helpful.
https://codelabs.developers.google.com/codelabs/firebase-android/ #1
https://github.com/firebase/friendlychat-android

add
I haven't used it very often, but it seems that I can wait for the image to be downloaded without going through Listener using the following methods:Getting the getBytes return value Task to synchronize with Tasks.wait and complete the read in for loop may be possible if the code around the display is not fiddling.
https://developers.google.com/android/guides/tasks

Firebase itself is intended for asynchronous implementation.I think it is possible to achieve synchronization by fixing the order of calls in Tasks or directly using RestAPI, but I recommend that you avoid it as much as possible and trace the implementation provided by Google.

https://developers-jp.googleblog.com/2016/09/become-a-firebase-taskmaster-part-1.html
https://stackoverflow.com/questions/31700830/is-it-possible-to-synchronously-load-data-from-firebase


2022-09-30 11:11

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.