LiveData观察者未被触发

huangapple go评论102阅读模式
英文:

LiveData observer not getting triggered

问题

我正在尝试从Firebase获取数据并显示它,但观察者未正常工作。我正在使用MVVM架构,因此我有一个 MainActivityViewModel,在其中从Firestore获取数据(一个 FirestoreMenu),然后在 MainActivity 中提供和观察它。但是,观察者从未触发。我按照一些解释LiveData如何工作的教程,但我不知道我做错了什么。有人能帮我找出问题吗?

MainActivity

  1. public class MainActivity extends AppCompatActivity {
  2. private FirebaseAuth mAuth;
  3. private MainActivityViewModel mainActivityViewModel;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_main);
  8. mAuth = FirebaseAuth.getInstance();
  9. FirebaseUser currentUser = mAuth.getCurrentUser();
  10. RecyclerView recyclerView = findViewById(R.id.recycle_view);
  11. recyclerView.setLayoutManager(new LinearLayoutManager(this));
  12. recyclerView.setHasFixedSize(true);
  13. final MenuAdapter adapter = new MenuAdapter();
  14. recyclerView.setAdapter(adapter);
  15. mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
  16. mainActivityViewModel.getMenus().observe(this, new Observer<List<FirestoreMenu>>() {
  17. @Override
  18. public void onChanged(List<FirestoreMenu> firestoreMenus) {
  19. // 更新RecyclerView
  20. adapter.setFirestoreMenus(firestoreMenus);
  21. }
  22. });
  23. // ... 其他部分
  24. }
  25. @Override
  26. public void onStart() {
  27. super.onStart();
  28. FirebaseUser currentUser = mAuth.getCurrentUser();
  29. signInAnonymously();
  30. }
  31. private void signInAnonymously() {
  32. // 实现匿名登录的代码
  33. }
  34. }

MainActivityViewModel

  1. public class MainActivityViewModel extends ViewModel {
  2. private MutableLiveData<List<FirestoreMenu>> mMenus;
  3. public MutableLiveData<List<FirestoreMenu>> getMenus() {
  4. if (mMenus == null) {
  5. mMenus = new MutableLiveData<>();
  6. }
  7. return mMenus;
  8. }
  9. public void setMenusCollection(String location) {
  10. FirebaseFirestore db = FirebaseFirestore.getInstance();
  11. CollectionReference menusRef = FirebaseFirestore.getInstance().collection("locations/" + location + "/menus");
  12. menusRef.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
  13. @Override
  14. public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
  15. ArrayList<FirestoreMenu> dataSet = new ArrayList<>();
  16. for (DocumentSnapshot document : queryDocumentSnapshots.getDocuments()) {
  17. FirestoreMenu menu = document.toObject(FirestoreMenu.class);
  18. dataSet.add(menu);
  19. }
  20. mMenus.setValue(dataSet);
  21. }
  22. });
  23. }
  24. }

MenuAdapter

  1. public class MenuAdapter extends RecyclerView.Adapter<MenuAdapter.MenuHolder> {
  2. private List<FirestoreMenu> firestoreMenus = new ArrayList<>();
  3. @NonNull
  4. @Override
  5. public MenuHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
  6. View itemView = LayoutInflater.from(parent.getContext())
  7. .inflate(R.layout.menu_item, parent, false);
  8. return new MenuHolder(itemView);
  9. }
  10. @Override
  11. public void onBindViewHolder(@NonNull MenuHolder holder, int position) {
  12. FirestoreMenu currentMenu = firestoreMenus.get(position);
  13. holder.textViewTitle.setText(currentMenu.getName());
  14. holder.textViewDescritpion.setText(currentMenu.getId());
  15. holder.textViewDescritpion.setText(currentMenu.getImage());
  16. }
  17. @Override
  18. public int getItemCount() {
  19. return firestoreMenus.size();
  20. }
  21. public void setFirestoreMenus(List<FirestoreMenu> menus) {
  22. this.firestoreMenus = menus;
  23. notifyDataSetChanged();
  24. }
  25. class MenuHolder extends RecyclerView.ViewHolder {
  26. private TextView textViewTitle;
  27. private TextView textViewDescritpion;
  28. private TextView textViewPriority;
  29. public MenuHolder(View itemView) {
  30. super(itemView);
  31. textViewTitle = itemView.findViewById(R.id.text_view_title);
  32. textViewDescritpion = itemView.findViewById(R.id.text_view_description);
  33. textViewPriority = itemView.findViewById(R.id.text_view_priority);
  34. }
  35. }
  36. }
英文:

I am trying to take data from the firebase and display it but the observer is not working. I am using a mvvm architecture , so I have a MainActivityViewModel where the data (a FirestoreMenu) is taken from the firestore and then it is provided and observed in the MainActivity. However, the observer is never triggered. I followed some tutorials that explain how LiveData works, but I have no idea what I am doing wrong. Can someone help me figure the problem out?

MainActivity

  1. public class MainActivity extends AppCompatActivity {
  2. private FirebaseAuth mAuth;
  3. private MainActivityViewModel mainActivityViewModel;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_main);
  8. mAuth = FirebaseAuth.getInstance();
  9. FirebaseUser currentUser = mAuth.getCurrentUser();
  10. RecyclerView recyclerView = findViewById(R.id.recycle_view);
  11. recyclerView.setLayoutManager(new LinearLayoutManager(this));
  12. recyclerView.setHasFixedSize(true);
  13. final MenuAdapter adapter = new MenuAdapter();
  14. recyclerView.setAdapter(adapter);
  15. mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
  16. mainActivityViewModel.getMenus().observe(this, new Observer&lt;List&lt;FirestoreMenu&gt;&gt;() {
  17. @Override
  18. public void onChanged(List&lt;FirestoreMenu&gt; firestoreMenus) {
  19. //update recycle view
  20. adapter.setFirestoreMenus(firestoreMenus);
  21. }
  22. });
  23. /* I also have tried this approach
  24. final MainActivityViewModel mMainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
  25. LiveData&lt;List&lt;FirestoreMenu&gt;&gt; mMenusList = mMainActivityViewModel.getMenus() ;
  26. final MenuListAdapter mAdapter = new MenuListAdapter(this, R.layout.adaptive_view_layout, mMainActivityViewModel.getMenus().getValue());
  27. mMenusList.observe(this, new Observer&lt;List&lt;FirestoreMenu&gt;&gt;() {
  28. @Override
  29. public void onChanged(List&lt;FirestoreMenu&gt; firestoreMenus) {
  30. mMainActivityViewModel.setMenusCollection(&quot;XmyTebpsvEyeBYBp2TUB&quot;);
  31. menusListView.setAdapter(mAdapter);
  32. }
  33. });
  34. */
  35. }
  36. @Override
  37. public void onStart() {
  38. super.onStart();
  39. FirebaseUser currentUser = mAuth.getCurrentUser();
  40. signInAnonymously();
  41. }
  42. private void signInAnonymously() {
  43. ...
  44. }
  45. }

MainActivityViewModel

  1. public class MainActivityViewModel extends ViewModel {
  2. private MutableLiveData&lt;List&lt;FirestoreMenu&gt;&gt; mMenus;
  3. public MutableLiveData&lt;List&lt;FirestoreMenu&gt;&gt; getMenus(){
  4. if (mMenus == null){
  5. mMenus = new MutableLiveData&lt;&gt;();
  6. }
  7. return mMenus;
  8. }
  9. public void setMenusCollection(String location){
  10. FirebaseFirestore db = FirebaseFirestore.getInstance();
  11. CollectionReference menusRef = FirebaseFirestore.getInstance().collection(&quot;locations/&quot;+location+&quot;/menus&quot;);
  12. menusRef.get().addOnSuccessListener(new OnSuccessListener&lt;QuerySnapshot&gt;() {
  13. @Override
  14. public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
  15. ArrayList&lt;FirestoreMenu&gt; dataSet = new ArrayList&lt;&gt;();
  16. for (DocumentSnapshot document : queryDocumentSnapshots.getDocuments()) {
  17. FirestoreMenu menu = document.toObject(FirestoreMenu.class);
  18. dataSet.add(menu);
  19. }
  20. mMenus.setValue(dataSet);
  21. }
  22. });
  23. }
  24. }

MenuAdapter

  1. public class MenuAdapter extends RecyclerView.Adapter&lt;MenuAdapter.MenuHolder&gt; {
  2. private List&lt;FirestoreMenu&gt; firestoreMenus= new ArrayList&lt;&gt;();
  3. @NonNull
  4. @Override
  5. public MenuHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
  6. View itemView = LayoutInflater.from(parent.getContext())
  7. .inflate(R.layout.menu_item,parent,false);
  8. return new MenuHolder(itemView);
  9. }
  10. @Override
  11. public void onBindViewHolder(@NonNull MenuHolder holder, int position) {
  12. FirestoreMenu currentMenu = firestoreMenus.get(position);
  13. holder.textViewTitle.setText(currentMenu.getName());
  14. holder.textViewDescritpion.setText(currentMenu.getId());
  15. holder.textViewDescritpion.setText(currentMenu.getImage());
  16. }
  17. @Override
  18. public int getItemCount() {
  19. return firestoreMenus.size();
  20. }
  21. public void setFirestoreMenus (List&lt;FirestoreMenu&gt; menus){
  22. this.firestoreMenus = menus;
  23. notifyDataSetChanged();
  24. }
  25. class MenuHolder extends RecyclerView.ViewHolder{
  26. private TextView textViewTitle;
  27. private TextView textViewDescritpion;
  28. private TextView textViewPriority;
  29. public MenuHolder(View itemView){
  30. super(itemView);
  31. textViewTitle = itemView.findViewById(R.id.text_view_title);
  32. textViewDescritpion = itemView.findViewById(R.id.text_view_description);
  33. textViewPriority = itemView.findViewById(R.id.text_view_priority);
  34. }
  35. }
  36. }

答案1

得分: 1

问题不在于观察者,我认为你的 Firebase 引用存在问题。

这就是为什么它没有进入你的成功回调中的 .collection("locations/" + location + "/menus") --> 检查这个引用,你应该使用 .document 导航到特定文档。

英文:

The problem is not in the observer, I think you have a problem with your Firebase reference.

That's why it does not enter in your onSuccess .collection(&quot;locations/&quot;+location+&quot;/menus&quot;) --> check this reference you should use .document to navigate to a certain document.

huangapple
  • 本文由 发表于 2020年8月7日 05:17:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63291868.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定