Как исправить ошибку onDataChange? - PullRequest
0 голосов
/ 21 мая 2019

Когда я возвращаюсь к MainActivity, где ViewPager.Приложение вылетает, когда я пишу сообщение пользователю.Поэтому, если что-то изменится в базе данных.

Я использую Windows 10 и Android Studio

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId 
        minSdkVersion 26
        targetSdkVersion 28
        versionCode 5
        versionName "1.5"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

Мой код

 public class ChatNotificationFragment extends Fragment {

    private FirebaseUser firebaseUser;
    private DatabaseReference reference;
    public ValueEventListener listener;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_chat_notification, container, false);

        firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());

        final TabLayout tabLayout = view.findViewById(R.id.tab_layout_chat);
        final ViewPager viewPager = view.findViewById(R.id.view_pager_chat);

        reference = FirebaseDatabase.getInstance().getReference("Chats");
        listener = reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                //ChatNotificationFragment.ViewPagerAdapter viewPagerAdapter = new ChatNotificationFragment.ViewPagerAdapter(getFragmentManager());
                ChatNotificationFragment.ViewPagerAdapter viewPagerAdapter = new ChatNotificationFragment.ViewPagerAdapter(getChildFragmentManager());
                int unread = 0;
                for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                    Chat chat = snapshot.getValue(Chat.class);
                    if (Objects.requireNonNull(chat).getReceiver().equals(firebaseUser.getUid()) && !chat.isIsseen()){
                        unread++;
                    }
                }

                if (unread == 0){
                    viewPagerAdapter.addFragment(new ChatsFragment(), "Chats");
                } else {
                    viewPagerAdapter.addFragment(new ChatsFragment(), "("+unread+") Chats");
                }
                viewPagerAdapter.addFragment(new NotificationFragment(), "Notification");
                viewPagerAdapter.addFragment(new UsersFragment(), "Users");
                viewPagerAdapter.addFragment(new SearchFragment(), "Search");
                viewPager.setAdapter(viewPagerAdapter);
                tabLayout.setupWithViewPager(viewPager);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
        return view;
    }

    // class ViewPagerAdapter extends FragmentPagerAdapter {
    class ViewPagerAdapter extends FragmentStatePagerAdapter {

        private final ArrayList<Fragment> fragments;
        private final ArrayList<String> titles;

        ViewPagerAdapter(FragmentManager fm){
            super(fm);
            this.fragments = new ArrayList<>();
            this.titles = new ArrayList<>();
        }

        @Override
        public Fragment getItem(int position) {
            return fragments.get(position);
        }

        @Override
        public int getCount() {
            return fragments.size();
        }

        void addFragment(Fragment fragment, String title){
            fragments.add(fragment);
            titles.add(title);
        }

        @Nullable
        @Override
        public CharSequence getPageTitle(int position) {
            return titles.get(position);
        }
    }

@Override
public void onDetach() {
    super.onDetach();
    reference.removeEventListener(listener);
}

}

Ошибка

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.bbinkconnect.bbinktattoo, PID: 22847
    java.lang.IllegalStateException: Fragment has not been attached yet.
        at androidx.fragment.app.Fragment.instantiateChildFragmentManager(Fragment.java:2383)
        at androidx.fragment.app.Fragment.getChildFragmentManager(Fragment.java:845)
        at com.bbinkconnect.bbinktattoo.fragments.ChatNotificationFragment$1.onDataChange(ChatNotificationFragment.java:53)
        at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@17.0.0:75)
        at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@17.0.0:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@17.0.0:55)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:6981)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)

Ответы [ 2 ]

1 голос
/ 21 мая 2019

Прямо как это

@Override
public void onDetach() {
    super.onDetach();
    // remove your listener here
    reference.removeEventListener()
}
0 голосов
/ 21 мая 2019

Вы можете создать ValueEventListener, как показано ниже, и затем добавить его в ссылку на базу данных.

// Declare this publicly in the class level
public ValueEventListener listener;

Затем в вашей функции onResume определите прослушиватель событий, как показано ниже, и затем добавьте прослушиватель к ссылке.

@Override
public void onResume {
    listener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            //ChatNotificationFragment.ViewPagerAdapter viewPagerAdapter = new ChatNotificationFragment.ViewPagerAdapter(getFragmentManager());
            ChatNotificationFragment.ViewPagerAdapter viewPagerAdapter = new ChatNotificationFragment.ViewPagerAdapter(getChildFragmentManager());
            int unread = 0;
            for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                Chat chat = snapshot.getValue(Chat.class);
                if (Objects.requireNonNull(chat).getReceiver().equals(firebaseUser.getUid()) && !chat.isIsseen()){
                    unread++;
                }
            }

            if (unread == 0){
                viewPagerAdapter.addFragment(new ChatsFragment(), "Chats");
            } else {
                viewPagerAdapter.addFragment(new ChatsFragment(), "("+unread+") Chats");
            }

            viewPagerAdapter.addFragment(new NotificationFragment(), "Notification");
            viewPagerAdapter.addFragment(new SearchFragment(), "Search");
            viewPager.setAdapter(viewPagerAdapter);
            tabLayout.setupWithViewPager(viewPager);
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
        }
    }

    // Add the listener to the database reference now. 
    reference.addValueEventListener(listener);
}

А затем в вашей функции onPause вам нужно удалить прослушиватель событий.

@Override
public void onPause() {
    super.onDetach();
    reference.removeEventListener(myListener);
}

Надеюсь, это решит вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...