首页 > 解决方案 > 我认为 datasnapshot 值返回 null 因为当我运行它时 TextView 为空,即使数据库 firebase 中有一个名称

问题描述

下面的代码是一个tictactoe游戏,但是我的问题是我想在这个活动中显示玩家的名字,他们的名字的输入来自另一个活动,该活动的代码在PlayerNames.java中。

Games.java 代码:

package com.example.tictactoe2;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;

import java.util.Objects;

public class Game extends AppCompatActivity {

FirebaseDatabase database = FirebaseDatabase.getInstance("https://playernames-default-rtdb.firebaseio.com/");
DatabaseReference dbRef = database.getReference();

Button [] buttons = new Button[9];

int p1Score, p2Score, playerStatus;
int p1ScoreCount, p2ScoreCount, rountCount;
boolean activePlayer;
int [] gameState = {2,2,2,2,2,2,2,2,2};

int [][] winPositions = {
        {0,1,2}, {3,4,5}, {6,7,8},
        {0,3,6}, {1,4,7}, {2,5,8},
        {0,4,8}, {2,4,6}
};



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game);

    TextView p1n = findViewById(R.id.p1);
    TextView p2n = findViewById(R.id.p2);

    Query pp = dbRef.child("Players");


    pp.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot nsnap: dataSnapshot.getChildren()) {
                    String p1 = (String) nsnap.child("1").getValue();
                    String p2 = (String) nsnap.child("2").getValue();

                    p1n.setText(p1);
                    p2n.setText(p2);
                }
            Toast.makeText(Game.this, "it worked", Toast.LENGTH_SHORT).show();

            }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Toast.makeText(Game.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });


    XoGame();


}

下面的代码用于用户在 EditText 中输入他们的姓名的活动,如下所示,第一个玩家是 p1Name,第二个是 p2Name。它们的名称通过设置值存储在数据库中。我检查过的名称已正确存储在数据库中。问题是当它从 Game.java 中的数据库中检索时。

PlayerNames.java 代码:

package com.example.tictactoe2;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

import java.util.ArrayList;

public class PlayerNames extends AppCompatActivity {

FirebaseDatabase database = FirebaseDatabase.getInstance("https://playernames-default-rtdb.firebaseio.com/");
DatabaseReference dbRef = database.getReference();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_player_names);

    EditText p1Name = findViewById(R.id.player1);
    EditText p2Name = findViewById(R.id.player2);

    Button cont = findViewById(R.id.contbtn);



    cont.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            String n1 = p1Name.getText().toString();
            String n2 = p2Name.getText().toString();


            dbRef.child("Players").push();
            dbRef.child("Players").child("1").setValue(n1);
            dbRef.child("Players").child("2").setValue(n2);


            Intent i = new Intent(PlayerNames.this, Game.class);
            startActivity(i);
        }
    });

}
}

我认为问题出在 DataSnapshot 的 for 循环中,或者可能是我将快照转换为 String 的地方。即使它在我检查的firebase的数据库中,它也没有显示玩家的名字。它显示为空。

firebase实时数据库:

从用户输入玩家名称的活动:
应该输出的TextView:

按继续后输出为空:

标签: javaandroidfirebasefirebase-realtime-database

解决方案


您需要在推送值时获取密钥,因为它将被视为树中的一个节点,然后设置您的String

String key = dbRef.child("Players").push().getKey();
dbRef.child("Players").child(key).child("1").setValue(n1);
dbRef.child("Players").child(key).child("2").setValue(n2);

并通过以下方式检索它们:

Query pp = dbRef.child("Players").child(key);
pp.addValueEventListener(new ValueEventListener() {
...

推荐阅读