Firebase存储OnSuccessListeners未及时成功

时间:2017-01-04 00:45:20

标签: android gridview firebase firebase-storage

经过彻底的调试后,我得出结论,我的GridView未显示任何图片的原因是因为OnSuccessListenersgetData()中的getImage()来自何时我从Firebase存储中获取缩略图和标题尚未成功。

我在getData()方法中执行了所有操作,我在用户选择onActivityResult中的Google地方信息后调用此方法。该方法应该实例化一个新的ImageItem(位图,字符串),但由于ImageItem尚未成功,因此返回空onSucessListeners。有任何想法吗?

    private void getData() {
        imageItems = new ArrayList<>();
        DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
        mDatabase.child((String) p.getName()).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Iterator<DataSnapshot> iter = dataSnapshot.getChildren().iterator();
                FirebaseStorage storage = FirebaseStorage.getInstance();
                StorageReference httpsReference = storage.getReferenceFromUrl(myUrl);
                while (iter.hasNext()) {
                    hasImage = false;
                    hasTitle = false;
                    HashMap<String, String> m = (HashMap<String, String>) iter.next().getValue();
                    String v = m.get("url");
                    Log.d("url", v);

                    String bu = m.get("bucket");
                    Log.d("bucket", bu);
                    b = getImage(bu, v);
                    StorageReference iR = httpsReference.child(bu).child("thumb");

                    httpsReference.child(bu).getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
                        @Override
                        public void onSuccess(StorageMetadata storageMetadata) {
                            // Metadata now contains the metadata for 'images/forest.jpg'
                            t = storageMetadata.getCustomMetadata("title");
                            hasTitle = true;
                            Log.d("title", t);
                        }
                    }).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception exception) {
                            Log.d("error", "ERROr");
                            // Uh-oh, an error occurred!
                        }
                    });


                    gridAdapter.data.add(new ImageItem(b, t, bu, v));


                }

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });


    }



public Bitmap getImage(String bx, String vu) {
    FirebaseStorage storage = FirebaseStorage.getInstance();
    StorageReference httpsReference = storage.getReferenceFromUrl(myUrl);


    String v = vu;
    Log.d("url", v);

    String bu = bx;
    Log.d("bucket", bu);
    StorageReference iR = httpsReference.child(bu).child("thumb");

    final long ONE_MEGABYTE = 1024 * 1024;
    iR.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
        @Override
        public void onSuccess(byte[] bytes) {
            // Data for "images/island.jpg" is returns, use this as needed
            b = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

            hasImage = true;
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            // Handle any errors
        }
    });
    return b;
}
}

****************更新1/7/2017 *********************

 private void getData() {
        imageItems = new ArrayList<>();
        DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
        mDatabase.child((String) p.getName()).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Iterator<DataSnapshot> iter = dataSnapshot.getChildren().iterator();
                FirebaseStorage storage = FirebaseStorage.getInstance();
                final StorageReference httpsReference = storage.getReferenceFromUrl("gs://socialnetwork-4b0c9.appspot.com");
                while (iter.hasNext()) {
                    hasImage = false;
                    hasTitle = false;
                    HashMap<String, String> m = (HashMap<String, String>) iter.next().getValue();
                    final String v = m.get("url");
                    Log.d("url", v);

                    final String bu = m.get("bucket");
                    Log.d("bucket", bu);
                    StorageReference iR = httpsReference.child(bu).child("thumb");
                    final long ONE_MEGABYTE = 1024 * 1024;
                    iR.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
                        @Override
                        public void onSuccess(byte[] bytes) {
                            // Data for "images/island.jpg" is returns, use this as needed
                            b = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

                            httpsReference.child(bu).getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
                                @Override
                                public void onSuccess(StorageMetadata storageMetadata) {
                                    // Metadata now contains the metadata for 'images/forest.jpg'
                                    t = storageMetadata.getCustomMetadata("title");
                                    hasTitle = true;
                                    gridAdapter.data.add(new ImageItem(b, t, bu, v));
                                    Log.d("title", t);
                                }
                            }).addOnFailureListener(new OnFailureListener() {
                                @Override
                                public void onFailure(@NonNull Exception exception) {
                                    Log.d("error", "ERROr");
                                    // Uh-oh, an error occurred!
                                }
                            });
                        }
                    }).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception exception) {
                            // Handle any errors
                        }
                    });


                }

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });


    }

************************用于网格和网格的方法*********

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == PLACE_AUTOCOMPLETE_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                Place place = PlaceAutocomplete.getPlace(this, data);
                p = place;

                gridView = (GridView) findViewById(R.id.grid_View);

                gridAdapter = new GridViewAdapter(this, R.layout.grid_item_layout);
                getData();
                gridView.setAdapter(gridAdapter);

                gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                        ImageItem item = (ImageItem) parent.getItemAtPosition(position);
                        //Create intent
                        Intent intent = new Intent(PlaceActivity.this, VideoActivity.class);
                        intent.putExtra("bucket", item.getBucket());
                        intent.putExtra("dUrl", item.getdUrl());


                        //Start details activity
                        startActivity(intent);
                    }
                });


            } else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
                Status status = PlaceAutocomplete.getStatus(this, data);
                // TODO: Handle the error.


            } else if (resultCode == RESULT_CANCELED) {
                // The user canceled the operation.
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

这是一个经典的异步编程问题:

var a = 1;

incrementAsync(function() {
  a = 2;
});

console.log(a);  // prints 1 because the function hasn't returned yet

您需要在异步函数中执行操作:

var a = 1;

incrementAsync(function() {
  a = 2;
  console.log(a);  // prints 2 now
});

所以我将你的功能重写为:

FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
FirebaseStorage mStorage = FirebaseStorage.getInstance();

mDatabase.getReference("...").addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
        ModelObject modelObject = storage.getValue(ModelObject.class);
        // Or just download the object here...
        mStorage.getReferenceFromUrl(modelObject.getUrl()).getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
            @Override
            public void onSuccess(StorageMetadata storageMetadata) {
                String title = storageMetadata.getCustomMetadata("title");
                gridAdapter.data.add(...);
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception exception) {
                // Uh-oh, an error occurred!
            }
        });
    }
    ...
});