Android: почему значение из базы данных Firebase не хранится должным образом? - PullRequest
0 голосов
/ 30 августа 2018

Код, который я использую для хранения значения uid child из базы данных firebase, выглядит следующим образом:

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                String data = (String) parent.getItemAtPosition(position);
                usersdRef.orderByChild("username").equalTo(parent.toString()).addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        for(DataSnapshot data: dataSnapshot.getChildren()){
                           String dataUID = data.child("uid").getValue(String.class);
                            toUid = dataUID;
                        }
                    }

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

                    }
                });

                Intent intent = new Intent(Main2Activity.this, Main5Activity.class);
                intent.putExtra("valueName", data);
                intent.putExtra("valueUID",toUid);
                startActivity(intent);

            }
        });

Но когда я пытаюсь использовать значение в другой деятельности, значение передается как ноль. Я получаю и использую значение как:

Bundle bundle = getIntent().getExtras();
        assert bundle != null;
        final String hName = bundle.getString("valueName");
        final String td = bundle.getString("valueUID");

hName хранится отлично, но td передается как ноль.

База данных Firebase выглядит примерно так:

firebase database

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Чтобы решить эту проблему, используйте следующий код:

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        String data = (String) parent.getItemAtPosition(position);

        String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
        DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
        DatabaseReference uidRef = rootRef.child("users").child(uid);
        ValueEventListener valueEventListener = new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String dataUID = dataSnapshot.child("uid").getValue(String.class);
                String dataUsername = dataSnapshot.child("username").getValue(String.class);

                Intent intent = new Intent(Main2Activity.this, Main5Activity.class);
                intent.putExtra("valueUID",dataUID);
                intent.putExtra("valueName", dataUsername);
                startActivity(intent);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Log.d(TAG, databaseError.getMessage());
            }
        };
        uidRef.addListenerForSingleValueEvent(valueEventListener);
    }
});

Вместо того, чтобы запрашивать всю базу данных, чтобы найти единственного пользователя, что является пустой тратой времени и ресурсов, вы можете получить ссылку на этого конкретного пользователя, используя его uid. Поэтому нет необходимости использовать метод getChildren() для циклического прохождения объекта DataSnapshot, поскольку вы можете просто получить его без цикла. Это правда, метод onDataChange() имеет асинхронное поведение, и весь код, касающийся намерения, должен быть помещен в обратный вызов. Если вы хотите использовать эти значения снаружи, я рекомендую вам посмотреть последнюю часть моего ответа из этого поста , в котором я объяснил, как это можно сделать с помощью пользовательского обратного вызова. Вы также можете взглянуть на это видео для лучшего понимания.

0 голосов
/ 30 августа 2018

Это потому, что вы пытаетесь получить доступ к значению переменной toUid вне фактического обратного вызова. Обратный вызов должен быть асинхронным, то есть вы не можете просто получить доступ к его результату на следующей строке после его определения. Ваш код в порядке, но в качестве идеи, доступ к этой переменной внутри метода обратного вызова, а не под сам обратный вызов

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        String data = (String) parent.getItemAtPosition(position);
        usersdRef.orderByChild("username").equalTo(parent.toString()).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for(DataSnapshot data: dataSnapshot.getChildren()){
                   String dataUID = data.child("uid").getValue(String.class);
                   toUid = dataUID;

                   Intent intent = new Intent(Main2Activity.this, Main5Activity.class);
                   intent.putExtra("valueName", data);
                   intent.putExtra("valueUID",toUid);
                   startActivity(intent);
            }
        }

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

            }
        });
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...