Android for循环不循环?火力地堡 [英] Android for loop not looping ? Firebase

查看:235
本文介绍了Android for循环不循环?火力地堡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,下面的代码:我不明白为什么我的for循环不循环之前 if(gameExists [0] == false){... 被调用。

 按钮playButton =(Button)findViewById(R.id.play_button); 
playButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){

user = mFirebaseAuth.getCurrentUser();

final String gameCateg = String.valueOf(categorySelected [0]);

DatabaseExference allExistingGamesToMatchKeys = mFirebaseDatabase.getReference()。child(gamestomatchkeys);
allExistingGamesToMatchKeys .addListenerForSingleValueEvent(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot){
final boolean [] gameExists = {false};
Log.d(gameExists (DataSnapshot postSnapshot:dataSnapshot.getChildren()){
final String currentKey = postSnapshot.getKey();
$ b b $ b //检查玩家2是n与player 1相同,以便我们不匹配同一个玩家
if(gameCateg.equals(postSnapshot.getValue()。toString())){
mFirebaseDatabase.getReference()。child (游戏))。child(currentKey).child(player1)。addListenerForSingleValueEvent(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot){
String namePlayer1 = dataSnapshot .getValue(String.class); $()()()()()()() ;
mFirebaseDatabase.getReference()。child(games)。child(currentKey).child(player2)。setValue(user.getUid());
gameExists [0] = true;
Log.d(gameExists in for loop,String.valueOf(gameExists [0]));


Intent intent = new Intent(getApplicationContext(),Game.class);
intent.putExtra(gameIdKey,currentKey);
startActivity(intent);


$ b @Override
public void onCancelled(DatabaseError databaseError){
}
});
break;

$ b $ if(gameExists [0] == false){
Log.d(gameExists in if,String.valueOf(gameExists [0]));

这就是我在我的日志中获得的顺序:


gameExists before循环:false

gameExists in if:false

gameExists in for循环:true

我不明白为什么我得到


gameExists in if:false

before


gameExists in for循环:true

我希望我的循环被调用并且在 if(gameExists [0] == false){... 之前完全循环,我该修改什么?



<为了简单起见,Firebase数据库请求不在代码流中。请注意,Firebase数据库请求不在代码流中。看看这个:

  //这里是第一个点
allExistingGamesToMatchKeys.addListenerForSingleValueEvent(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot){
// here is second point
}
...
}
//这里是第三点

上面的例子将会像这样执行


- >第一点 - >第三点

然后第二个点?当Firebase从在线数据库获取数据时,第二点将被执行,因此它在流程之外(但大多数情况下,它将在第三点之后执行



因此,如果您需要在Firebase请求完成后执行一些代码,请将其放在 onDataChange()


您可以看在这供参考



I have an issue with the following code : I don't understand why my for-loop doesn't loop before if (gameExists[0] == false){... is called.

    Button playButton = (Button) findViewById(R.id.play_button);
    playButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            user = mFirebaseAuth.getCurrentUser();

            final String gameCateg = String.valueOf(categorySelected[0]);

            DatabaseReference allExistingGamesToMatchKeys = mFirebaseDatabase.getReference().child("gamestomatchkeys");
              allExistingGamesToMatchKeys.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    final boolean[] gameExists = {false};
                    Log.d("gameExists before loop ", String.valueOf(gameExists[0]));

                    for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
                        final String currentKey = postSnapshot.getKey();
                        //check player 2 is not the same as player 1 so that we don't match the same player
                        if(gameCateg.equals(postSnapshot.getValue().toString())){
                            mFirebaseDatabase.getReference().child("games").child(currentKey).child("player1").addListenerForSingleValueEvent(new ValueEventListener() {
                                @Override
                                public void onDataChange(DataSnapshot dataSnapshot) {
                                    String namePlayer1 = dataSnapshot.getValue(String.class);
                                    if(!(user.getUid().toString().equals(namePlayer1))){
                                        mFirebaseDatabase.getReference().child("gamestomatchkeys").child(currentKey).removeValue();
                                        mFirebaseDatabase.getReference().child("games").child(currentKey).child("player2").setValue(user.getUid());
                                    gameExists[0] = true;
                                    Log.d("gameExists in for loop ", String.valueOf(gameExists[0]));


                                    Intent intent = new Intent(getApplicationContext(), Game.class);
                                        intent.putExtra("gameIdKey", currentKey);
                                        startActivity(intent);
                                    }
                                }

                                @Override
                                public void onCancelled(DatabaseError databaseError) {
                                }
                            });
                            break;
                        }
                    }
                    if (gameExists[0] == false){
                        Log.d("gameExists in if", String.valueOf(gameExists[0]));

This is what I get in my logs, in this order :

gameExists before loop: false

gameExists in if: false

gameExists in for loop: true

I don't understand why I get

gameExists in if: false

before

gameExists in for loop: true

I want my loop to be called and entirely looped before if (gameExists[0] == false){..., what should I modify ?

Thank you !

解决方案

To make it simple, Firebase Database request are outside of the code flow. Take a look at this:

// here is first point 
allExistingGamesToMatchKeys.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        // here is second point
    }
    ...
}
// here is third point

Above example will be executed like this

--> first point --> third point

Then where is the second point? Second point will be executed whenever Firebase get data from online database, so it is outside the flow (but most of the time, it will be executed after the third point.

So in conclusion, if you need some code to be executed after Firebase requests is done, place it inside onDataChange()

You might look at this for reference

这篇关于Android for循环不循环?火力地堡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆