addChildEventListener不起作用

时间:2018-02-23 14:51:18

标签: java android firebase firebase-realtime-database

在我的应用中,我想将数据添加到Firebase数据库并同时读取数据。所以我使用addChildEventListener()方法来检索数据。但是这种方法不起作用,应用程序每次都会崩溃。 代码如下:

public class ChatActivity extends AppCompatActivity {

LinearLayout layout;
RelativeLayout layout_2;
ImageView sendButton;
EditText messageArea;
ScrollView scrollView;
//Firebase reference1, reference2;
private DatabaseReference reference1, reference2,reference3;
private FirebaseAuth firebaseAuth;
private FirebaseUser firebaseUser;
private String username,userId;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_chat);

    layout = (LinearLayout) findViewById(R.id.layout1);
    layout_2 = (RelativeLayout)findViewById(R.id.layout2);
    sendButton = (ImageView)findViewById(R.id.sendButton);
    messageArea = (EditText)findViewById(R.id.messageArea);
    scrollView = (ScrollView)findViewById(R.id.scrollView);
    username=getIntent().getStringExtra("abc");
    userId=getIntent().getStringExtra("abcd");

    reference1= FirebaseDatabase.getInstance().getReferenceFromUrl("https://career-dna-bec2e.firebaseio.com/CHAT/user/" +username);
    reference2=FirebaseDatabase.getInstance().getReferenceFromUrl("https://career-dna-bec2e.firebaseio.com/CHAT/admin/"+username);

    sendButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String messageText = messageArea.getText().toString();

            if(!messageText.equals("")){
                Map<String, String> map = new HashMap<String, String>();
                map.put("message", messageText);
                map.put("user",userId);
                reference1.push().setValue(map);
                reference2.push().setValue(map);
                messageArea.setText("");
            }
        }
    });
    try
    {
        reference1.addChildEventListener(new com.google.firebase.database.ChildEventListener() {
            @Override
            public void onChildAdded(com.google.firebase.database.DataSnapshot dataSnapshot, String s) {
                Map<String, String> map = dataSnapshot.getValue(Map.class);
                String message = map.get("message").toString();
                String userName = map.get("user").toString();

                if(userName.equals(userId)){
                    addMessageBox("You:-\n" + message, 1);
                }
                else{
                    addMessageBox("admin"+ ":-\n" + message, 2);
                }
            }

            @Override
            public void onChildChanged(com.google.firebase.database.DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onChildRemoved(com.google.firebase.database.DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(com.google.firebase.database.DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }
    catch (Exception e)
    {
        Toast.makeText(getApplicationContext(),"error:"+e,Toast.LENGTH_SHORT).show();
    }

}

该应用程序因此错误而崩溃:

  

02-23 20:43:15.832 12583-12583 / com.ankush.anthroplace.careerdna   E / AndroidRuntime:FATAL EXCEPTION:主要流程:   com.ankush.anthroplace.careerdna,PID:12583   com.google.firebase.database.DatabaseException:类java.util.Map   有泛型类型参数,请改用GenericTypeIndicator

2 个答案:

答案 0 :(得分:0)

尝试使用:

Map<String, Object> map = new HashMap<String, Object>();

检索数据时请使用:

Map<String, Object> map = dataSnapshot.getValue(Map.class);

但是,如果你真的想使用带有2个字符串的Map类作为参数,请在onChildAdded方法中使用: -

GenericTypeIndicator<Map<String, String>> genericTypeIndicator = new GenericTypeIndicator<Map<String, String>>() {};
Map<String, String> map = dataSnapshot.getValue(genericTypeIndicator);

无需输入完整的网址,请改用

DatabaseReference reference1 = FirebaseDatabase.getInstance().getReference().child("CHAT").child("user").child(username);
DatabaseReference reference2 = FirebaseDatabase.getInstance().getReference().child("CHAT").child("admin").child(username);

而且,你做错了的另一件事是,你每次点击sendButton时都要添加ChildEventListener,这不是必需的,只需在onCreate()中创建一个ChildEventListener而不是像on This()那样: -

    ChildEventListener childEventListener = new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            Map<String, String> map = dataSnapshot.getValue(Map.class);
            String message = map.get("message").toString();
            String userName = map.get("user").toString();

            if(userName.equals(userId)){
                addMessageBox("You:-\n" + message, 1);
            }
            else{
                addMessageBox("admin"+ ":-\n" + message, 2);
            }
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e("TAG", databaseError.toString());
        }
    };
//attaching the ChildEventListener to the DatabaseReference
reference1.addChildEventListener(childEventListener);

不要忘记在onStop()

中删除侦听器
@Override
protected void onStop() {
    super.onStop();
    reference1.removeEventListener(childEventListener);
}

答案 1 :(得分:0)

我通过使用对象存储数据而不是hashmap来解决问题。我不确定为什么地图不起作用,但使用对象做得很好。 代码如下:

    sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String messageText = messageArea.getText().toString();

                if(!messageText.equals("")){

                    map=new messageModel(messageText,userId);
                    reference1.child(""+n).setValue(map).addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            if(task.isSuccessful())
                            {
                                reference2.child(""+n2).setValue(map).addOnCompleteListener(new OnCompleteListener<Void>() {
                                    @Override
                                    public void onComplete(@NonNull Task<Void> task) {
                                        if(task.isSuccessful())
                                        {
                                            messageArea.setText("");
                                        }

                                    }
                                });
                            }
                            else
                            {
                                Toast.makeText(getApplicationContext(),"server problem try again",Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
                }
            }
        });
        try
        {
            reference1.addChildEventListener(new com.google.firebase.database.ChildEventListener() {
                @Override
                public void onChildAdded(com.google.firebase.database.DataSnapshot dataSnapshot, String s) {
                    map = dataSnapshot.getValue(messageModel.class);
                    String message = map.myMessage;
                    String userName = map.user;

                    if(userName.equals(userId)){
                        addMessageBox("You:\n" + message, 1);
                    }
                    else{
                        addMessageBox("USER:\n" + message, 2);
                    }
                }

                @Override
                public void onChildChanged(com.google.firebase.database.DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onChildRemoved(com.google.firebase.database.DataSnapshot dataSnapshot) {

                }

                @Override
                public void onChildMoved(com.google.firebase.database.DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });
        }
        catch (Exception e)
        {
            Toast.makeText(getApplicationContext(),"error:"+e,Toast.LENGTH_SHORT).show();
        }

你可以看到代码的任何部分都没有被改变,除了地图部分.messoModel类的代码如下:

public class messageModel {
public String myMessage;
public String user;
public messageModel()
{

}
public messageModel(String a,String b)
{
    myMessage=a;
    user=b;
}

}