for循环未在单值事件监听器内运行

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

for loop not running inside single value event listener

问题

我正在尝试实现一个搜索功能,在点击搜索结果后,我会在一个片段中显示用户的详细信息。问题出现在 init() 函数中,onDataChange() 函数内部的 foreach 循环不会执行。

  1. private User mUser;
  2. @Nullable
  3. @Override
  4. public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  5. View view = inflater.inflate(R.layout.fragment_view_profile, container, false);
  6. try{
  7. mUser = getUserFromBundle();
  8. init();
  9. }catch (NullPointerException e){
  10. Log.e(TAG, "onCreateView: NullPointerException: " + e.getMessage() );
  11. setupFirebaseAuth();
  12. return view;
  13. }
  14. }
  15. private void init(){
  16. DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
  17. Query query = reference.child(getString(R.string.db_user_account_settings)).orderByChild(getString(R.string.field_user_id)).equalTo(mUser.getUserid());
  18. query.addListenerForSingleValueEvent(new ValueEventListener() {
  19. @Override
  20. public void onDataChange(DataSnapshot dataSnapshot) {
  21. for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
  22. UserSettings settings = new UserSettings();
  23. settings.setUser(mUser);
  24. settings.setSettings(singleSnapshot.getValue(UserAccountSettings.class));
  25. setProfileWidgets(settings);
  26. }
  27. }
  28. @Override
  29. public void onCancelled(@NonNull DatabaseError databaseError) {
  30. throw databaseError.toException();
  31. }
  32. });
  33. }
  34. private User getUserFromBundle(){
  35. Bundle bundle = this.getArguments();
  36. if(bundle != null){
  37. return bundle.getParcelable(getString(R.string.intent_user));
  38. }else{
  39. return null;
  40. }
  41. }

strings.xml

  1. <resources>
  2. <string name="field_user_id">user_id</string>
  3. <string name="intent_user">intent_user</string>
  4. <string name="db_user_account_settings">user_account_settings</string>
  5. </resources>

我不知道为什么这不起作用。


从评论中:

for循环未在单值事件监听器内运行

1),2)我已经添加了你可以参考的 strings.xml 代码 3)屏幕截图中的蓝色箭头显示了返回的用户ID(这正是我想要的) 4)红色部分是我正在查询的内容 5)是的,我对 JSON 和 Firebase 有点陌生。

英文:

I'm trying to implement a search feature where, upon clicking on the search result, I display the user's details in a fragment. The problem is in the init() function where the foreach loop inside the onDataChange() funcion doesn't execute.

  1. private User mUser;
  2. @Nullable
  3. @Override
  4. public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  5. View view = inflater.inflate(R.layout.fragment_view_profile, container, false);
  6. try{
  7. mUser = getUserFromBundle();
  8. init();
  9. }catch (NullPointerException e){
  10. Log.e(TAG, &quot;onCreateView: NullPointerException: &quot; + e.getMessage() );
  11. setupFirebaseAuth();
  12. return view;
  13. }
  14. private void init(){
  15. DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
  16. Query query = reference.child(getString(R.string.db_user_account_settings)).orderByChild(getString(R.string.field_user_id)).equalTo(mUser.getUserid());
  17. query.addListenerForSingleValueEvent(new ValueEventListener() {
  18. @Override
  19. public void onDataChange(DataSnapshot dataSnapshot) {
  20. for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
  21. UserSettings settings = new UserSettings();
  22. settings.setUser(mUser);
  23. settings.setSettings(singleSnapshot.getValue(UserAccountSettings.class));
  24. setProfileWidgets(settings);
  25. }
  26. }
  27. @Override
  28. public void onCancelled(@NonNull DatabaseError databaseError) {
  29. throw databaseError.toException();
  30. }
  31. });
  32. }
  33. private User getUserFromBundle(){
  34. Bundle bundle = this.getArguments();
  35. if(bundle != null){
  36. return bundle.getParcelable(getString(R.string.intent_user));
  37. }else{
  38. return null;
  39. }
  40. }

strings.xml

  1. &lt;resources&gt;
  2. &lt;string name=&quot;field_user_id&quot;&gt;user_id&lt;/string&gt;
  3. &lt;string name=&quot;intent_user&quot;&gt;intent_user&lt;/string&gt;
  4. &lt;string name=&quot;db_user_account_settings&quot;&gt;user_account_settings&lt;/string&gt;
  5. &lt;/resources

I have no idea why this isn't working.


From comment:

for循环未在单值事件监听器内运行

> 1), 2) I've added the strings.xml code you can refer to 3) The blue arrow in the screenshot shows the userid that is returned (which is exactly what I want) 4) The red portion is what I'm querying 5) Yes. I'm a bit new with JSON and firebase,

答案1

得分: 1

你的代码执行以下操作:

  1. reference.child("user_account_settings").orderByChild("user_id").equalTo(mUser.getUserid())

这将:

  1. 获取user_account_settings下的所有子节点。
  2. 根据它们的user_id属性的值进行排序。
  3. 仅选择该值存在且等于UID的节点。

由于你展示的 JSON 中没有显示user_id属性,所以没有结果。

如果你要查找的值作为节点的键,你可以直接使用child(...)来查找该节点。并且由于具有给定键的节点只能有一个子节点,这意味着你在onDataChange方法中不再需要对getChildren()进行循环。

所以类似这样的代码:

  1. DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
  2. Query query = reference.child(getString(R.string.db_user_account_settings)).child(mUser.getUserid());
  3. query.addListenerForSingleValueEvent(new ValueEventListener() {
  4. @Override
  5. public void onDataChange(DataSnapshot dataSnapshot) {
  6. UserSettings settings = new UserSettings();
  7. settings.setUser(mUser);
  8. settings.setSettings(singleSnapshot.getValue(UserAccountSettings.class));
  9. setProfileWidgets(settings);
  10. }
  11. @Override
  12. public void onCancelled(@NonNull DatabaseError databaseError) {
  13. throw databaseError.toException();
  14. }
  15. });
英文:

Your code does:

  1. reference.child(getString(R.string.db_user_account_settings)).orderByChild(getString(R.string.field_user_id)).equalTo(mUser.getUserid())

Which translates to:

  1. reference.child(&quot;user_account_settings&quot;).orderByChild(&quot;user_id&quot;).equalTo(mUser.getUserid())

So it:

  1. Takes all child nodes under user_account_settings.
  2. Orders them on the value of their user_id property.
  3. Selects only the nodes where that value exists and is equal to the UID.

Since the JSON you showed doesn't show a user_id property, there are no results.

If you have the value you are looking for as the key of a node, you can just use child(...) to look that node up. And since there can only be one child node with a given key, that means you no longer need the loop over getChildren() in the onDataChange method.

So something like:

  1. DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
  2. Query query = reference.child(getString(R.string.db_user_account_settings)).child(mUser.getUserid());
  3. query.addListenerForSingleValueEvent(new ValueEventListener() {
  4. @Override
  5. public void onDataChange(DataSnapshot dataSnapshot) {
  6. UserSettings settings = new UserSettings();
  7. settings.setUser(mUser);
  8. settings.setSettings(singleSnapshot.getValue(UserAccountSettings.class));
  9. setProfileWidgets(settings);
  10. }
  11. @Override
  12. public void onCancelled(@NonNull DatabaseError databaseError) {
  13. throw databaseError.toException();
  14. }
  15. });

huangapple
  • 本文由 发表于 2020年9月14日 00:30:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/63873058.html
匿名

发表评论

匿名网友

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

确定