如何从setValue Firebase数据库退出?

时间:2018-10-25 13:39:46

标签: java android firebase firebase-realtime-database

我有一个用于更改数据库条目messageText的代码:

@Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.edit:
                AdapterView.AdapterContextMenuInfo tm = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
                int position = tm.position;
                final DatabaseReference ref = adapter.getRef(position);
                ref.child("messageUserId").addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        if (FirebaseAuth.getInstance().getCurrentUser().getUid().equals(dataSnapshot.getValue().toString())) {
                            ref.child("messageText").addValueEventListener(new ValueEventListener() {
                                @Override
                                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                    input.setText(dataSnapshot.getValue().toString());
                                    sendMessage.setOnClickListener(new View.OnClickListener() {
                                        @Override
                                        public void onClick(View v) {
                                            ref.child("messageText").setValue(input.getText().toString());
                                            input.getText().clear();

                                            Toast.makeText(Chat.this, "Изменено", Toast.LENGTH_SHORT).show();
                                        }
                                    });
                                }

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

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {
                    }
                });
                break;
        }
        return false;
    }

代码ref.child("messageText").setValue(input.getText().toString())的效果很好,但是在代码重新启动之后,

public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
     input.setText(dataSnapshot.getValue().toString());

一切都转了一圈-messageText的数据被插入EditText input中,我可以再次更改文本。

如何在第一次更改messageText之后停止执行代码?

2 个答案:

答案 0 :(得分:1)

ValueEventListener的onDataChange()方法:

  

将使用此位置的数据快照调用此方法。每次数据更改时也会调用它。

换句话说,即使它是写,更新或删除操作,也会触发此方法。在您的情况下也是如此,您正在使用相同的引用ref.child("messageText")来添加数据并侦听更改,因此这就是您的行为。这是一遍又一遍地发生。为了解决这个问题,您需要通过创建两个不同的事件来更改代码的逻辑。 onClick可以将数据写入数据库并附加侦听器,从而使其与该事件无关。

答案 1 :(得分:0)

正确的代码:

      @Override
public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.edit:
            AdapterView.AdapterContextMenuInfo tm = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
            int position = tm.position;
            editText = adapter.getRef(position);


            editText.child("messageUserId").addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    if (FirebaseAuth.getInstance().getCurrentUser().getUid().equals(dataSnapshot.getValue())) {
                        editText.child("messageText").addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                input.setText(dataSnapshot.getValue().toString());

                                editMessage();
                            }

                            @Override
                            public void onCancelled(@NonNull DatabaseError databaseError) {

                            }
                        });
                    } else {
                        Toast.makeText(Chat.this, "Запрещено", Toast.LENGTH_SHORT).show();
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });
    }
    return true;
}

private void editMessage() {
    sendMessage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            editText.child("messageText").setValue(input.getText().toString());
            Toast.makeText(Chat.this, "Изменено", Toast.LENGTH_SHORT).show();
            input.getText().clear();
            sendMessage();
        }
    });
}

private void sendMessage() {
    sendMessage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (input.getText().toString().trim().equals("")) {
                Toast.makeText(Chat.this, getString(R.string.edittext_null), Toast.LENGTH_SHORT).show();
            } else {
                FirebaseDatabase.getInstance()
                        .getReference()
                        .push()
                        .setValue(new ChatMessage(input.getText().toString(),
                                Objects.requireNonNull(FirebaseAuth.getInstance().getCurrentUser()).getDisplayName(),
                                FirebaseAuth.getInstance().getCurrentUser().getUid(),
                                payload,
                                avatar,
                                uploadedAttach
                        ));
                input.setText("");
            }
        }
    });
}

必须简单地将其原始操作返回到按钮,并使用addListenerForSingleValueEvent代替addValueEventListener