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

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

for loop not running inside single value event listener

问题

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

private User mUser;

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

    try{
        mUser = getUserFromBundle();
        init();
    }catch (NullPointerException e){
        Log.e(TAG, "onCreateView: NullPointerException: "  + e.getMessage() );
        setupFirebaseAuth();
        return view;
    }
}

private void init(){
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
    Query query = reference.child(getString(R.string.db_user_account_settings)).orderByChild(getString(R.string.field_user_id)).equalTo(mUser.getUserid());
    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot singleSnapshot :  dataSnapshot.getChildren()){
                UserSettings settings = new UserSettings();
                settings.setUser(mUser);
                settings.setSettings(singleSnapshot.getValue(UserAccountSettings.class));
                setProfileWidgets(settings);
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            throw databaseError.toException();
        }
    });
}

private User getUserFromBundle(){
    Bundle bundle = this.getArguments();
    if(bundle != null){
        return bundle.getParcelable(getString(R.string.intent_user));
    }else{
        return null;
    }
}

strings.xml

<resources>
    <string name="field_user_id">user_id</string>    
    <string name="intent_user">intent_user</string>    
    <string name="db_user_account_settings">user_account_settings</string>  
</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.

private User mUser;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_view_profile, container, false);
try{
mUser = getUserFromBundle();
init();
}catch (NullPointerException e){
Log.e(TAG, &quot;onCreateView: NullPointerException: &quot;  + e.getMessage() );
setupFirebaseAuth();
return view;
}
private void init(){
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference.child(getString(R.string.db_user_account_settings)).orderByChild(getString(R.string.field_user_id)).equalTo(mUser.getUserid());
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot singleSnapshot :  dataSnapshot.getChildren()){
UserSettings settings = new UserSettings();
settings.setUser(mUser);
settings.setSettings(singleSnapshot.getValue(UserAccountSettings.class));
setProfileWidgets(settings);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
private User getUserFromBundle(){
Bundle bundle = this.getArguments();
if(bundle != null){
return bundle.getParcelable(getString(R.string.intent_user));
}else{
return null;
}
}

strings.xml

&lt;resources&gt;
&lt;string name=&quot;field_user_id&quot;&gt;user_id&lt;/string&gt;    
&lt;string name=&quot;intent_user&quot;&gt;intent_user&lt;/string&gt;    
&lt;string name=&quot;db_user_account_settings&quot;&gt;user_account_settings&lt;/string&gt;  
&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

你的代码执行以下操作:

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()进行循环。

所以类似这样的代码:

DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference.child(getString(R.string.db_user_account_settings)).child(mUser.getUserid());
query.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        UserSettings settings = new UserSettings();
        settings.setUser(mUser);
        settings.setSettings(singleSnapshot.getValue(UserAccountSettings.class));
        setProfileWidgets(settings);
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        throw databaseError.toException();
    }
});
英文:

Your code does:

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

Which translates to:

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:

DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference.child(getString(R.string.db_user_account_settings)).child(mUser.getUserid());
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
UserSettings settings = new UserSettings();
settings.setUser(mUser);
settings.setSettings(singleSnapshot.getValue(UserAccountSettings.class));
setProfileWidgets(settings);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});

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:

确定