从firebase检索图像会多次显示相同的图像

时间:2017-08-23 07:08:32

标签: android firebase imageview firebase-storage

MainActivity

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    public static final String ANONYMOUS = "anonymous";
    public static final int RC_SIGN_IN = 1;
    private static final int RC_PHOTO_PICKER = 2;
    private String mUsername;

    // Firebase instance variables
    private FirebaseDatabase mFirebaseDatabase;
    private DatabaseReference mMessagesDatabaseReference;
    private ChildEventListener mChildEventListener;
    private FirebaseAuth mFirebaseAuth;
    private FirebaseAuth.AuthStateListener mAuthStateListener;
    private FirebaseStorage mFirebaseStorage;
    private StorageReference mChatPhotosStorageReference;
    private FirebaseRemoteConfig mFirebaseRemoteConfig;
    private ProgressBar progressBar;

    private RecyclerView recyclerView;
    private FloatingActionButton floatingActionButton;

    PhotosAdapter contactsAdapter;
    List<Photos> contactList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        progressBar=(ProgressBar)findViewById(R.id.progressbar);
        mUsername = ANONYMOUS;
        recyclerView=(RecyclerView)findViewById(R.id.recyclerview);
        floatingActionButton=(FloatingActionButton)findViewById(R.id.floatingactionbutton);
        contactList = new ArrayList();
        progressBar.setVisibility(View.GONE);
        // Initialize Firebase components
        mFirebaseDatabase = FirebaseDatabase.getInstance();
        mFirebaseAuth = FirebaseAuth.getInstance();
        mFirebaseStorage = FirebaseStorage.getInstance();
        mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();


        mMessagesDatabaseReference = mFirebaseDatabase.getReference().child("messages");
        mChatPhotosStorageReference = mFirebaseStorage.getReference().child("chat_photos");

        mAuthStateListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                if (user != null) {
                    // User is signed in
                    onSignedInInitialize(user.getDisplayName());
                } else {
                    // User is signed out
                    onSignedOutCleanup();
                    startActivityForResult(
                            AuthUI.getInstance()
                                    .createSignInIntentBuilder()
                                    .setIsSmartLockEnabled(false)
                                    .setProviders(
                                            AuthUI.EMAIL_PROVIDER,
                                            AuthUI.GOOGLE_PROVIDER)
                                    .build(),
                            RC_SIGN_IN);
                }
            }
        };




        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                intent.setType("image/jpeg");
                intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
                startActivityForResult(Intent.createChooser(intent, "Complete action using"), RC_PHOTO_PICKER);

            }
        });


        mMessagesDatabaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot snapshot) {

                for (DataSnapshot postSnapshot : snapshot.getChildren()) {

                    Photos imageUploadInfo = postSnapshot.getValue(Photos.class);
                    if(!contactList.contains(imageUploadInfo)){
                        contactList.add(imageUploadInfo);
                        Log.i(TAG, "onDataChange: "+contactList);
                    }

                }

                contactsAdapter=new PhotosAdapter(contactList,getApplicationContext());
                progressBar.setVisibility(View.GONE);

                recyclerView.setAdapter(contactsAdapter);

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {



            }
        });

        recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(),5));
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RC_SIGN_IN) {
            if (resultCode == RESULT_OK) {
                // Sign-in succeeded, set up the UI
                Toast.makeText(this, "Signed in!", Toast.LENGTH_SHORT).show();
            } else if (resultCode == RESULT_CANCELED) {
                // Sign in was canceled by the user, finish the activity
                Toast.makeText(this, "Sign in canceled", Toast.LENGTH_SHORT).show();
                finish();
            }
        }else if (requestCode == RC_PHOTO_PICKER && resultCode == RESULT_OK) {
            Uri selectedImageUri = data.getData();

            // Get a reference to store file at chat_photos/<FILENAME>
            StorageReference photoRef = mChatPhotosStorageReference.child(selectedImageUri.getLastPathSegment());

            // Upload file to Firebase Storage
            photoRef.putFile(selectedImageUri)
                    .addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                            // When the image has successfully uploaded, we get its download URL
                          //  progressBar.setVisibility(View.VISIBLE);
                            Uri downloadUrl = taskSnapshot.getDownloadUrl();

                            // Set the download URL to the message box, so that the user can send it to the database
                            Photos friendlyMessage = new Photos(downloadUrl.toString());
                            mMessagesDatabaseReference.push().setValue(friendlyMessage);
                        }
                    });
        }
    }
    @Override
    protected void onResume() {
        super.onResume();
        mFirebaseAuth.addAuthStateListener(mAuthStateListener);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mAuthStateListener != null) {
            mFirebaseAuth.removeAuthStateListener(mAuthStateListener);
        }
    }

    private void onSignedInInitialize(String username) {
        mUsername = username;

    }

    private void onSignedOutCleanup() {
        mUsername = ANONYMOUS;

    }
}

假设我将图像上传到firebase存储,它会在app的recyclerview的imageview中检索到。当我上传第二张图片时,第一张图片会在我的应用中显示两次,第二张图片会显示一次。当我上传第三张图像时,第一张图像显示三次,第二张图像显示两次,第三张图像一次显示。我知道问题出在mMessagesDatabaseReference.addValueEventListener,但我无法弄明白。请帮帮我..

2 个答案:

答案 0 :(得分:1)

我想在每次新上传时都会调用onDataChange所有数据。因此,您必须在添加项目之前清除contactList,例如:

public void onDataChange(DataSnapshot snapshot) {
    contactList.clear()

    for (DataSnapshot postSnapshot : snapshot.getChildren()) {
        Photos imageUploadInfo = postSnapshot.getValue(Photos.class);
        if(!contactList.contains(imageUploadInfo)){
            contactList.add(imageUploadInfo);
            Log.i(TAG, "onDataChange: "+contactList);
        }
    }

    contactsAdapter=new PhotosAdapter(contactList,getApplicationContext());
    progressBar.setVisibility(View.GONE);

    recyclerView.setAdapter(contactsAdapter);
}

答案 1 :(得分:0)

使用ChildEventListener代替value event listener。 值事件侦听器在单个更改时再次获取所有数据,因此对于添加图像2,还将在值事件中接收图像1。 在ChildEventListener中,您可以将方法onChildAdded()添加到回收站。

像这样使用子事件监听器,不需要for循环,在添加子进程时会调用它,避免需要进行循环

在添加项目后也不要忘记在recyclerAdapter上调用notify以显示视图上的更改

在onCreate方法中移动它们并在那里初始化:

contactList = new ArrayList();
contactsAdapter=new PhotosAdapter(contactList,getApplicationContext());

recyclerView.setAdapter(contactsAdapter);

从firebase获取子代码的代码

private void attachDatabaseReadListener() {
        if (mChildEventListener == null) {
            mChildEventListener = new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                        Photos imageUploadInfo = dataSnapshot.getValue(Photos.class);
                        if (!contactList.contains(imageUploadInfo)) {
                            contactList.add(imageUploadInfo);
                        }

                }

                @Override
                public void onChildChanged(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onChildRemoved(DataSnapshot dataSnapshot) {

                }

                @Override
                public void onChildMoved(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            }
            mMessagesDatabaseReference.addChildEventListener(mChildEvent‌​Listener);
        }
    }