1

I don't know exactly how to work with nested data. It's a quiz app.

I have the following database structure: The quiz has one or more questions and each question has one or more answers.

I'm trying to do in my Java classes something like:

public class Questionario implements Serializable, Parcelable {
    @PrimaryKey
    private String id;
    private String titulo;
    private String admin;
    private Pergunta pergunta;`

public class Pergunta implements Serializable, Parcelable {
    @PrimaryKey
    private String id;
    private String descricao;
    private Resposta resposta;`

public class Resposta implements Serializable {
    @PrimaryKey
    private String id;
    private String descricao;
    private String dica;`

It's going to be only one Questionario (quiz) object right now. Then I need to create Pergunta (question) objects and then create Resposta (answer) objects.

I need to show the objects in a RecyclerView & CardView.

About new Pergunta and Resposta: I was thinking about different screens to create them and then link them somehow (maybe with Context: when I click in a "Cadastrar Resposta" button on a card view with a Pergunta object it goes to a form to create a new Resposta object like this and when I click in a "Listar Respostas" button it goes to a another RecyclerView & CardView with the Resposta objects listed like this). The other buttons (excluir & editar) are to delete and edit objects respectively.

I tried something like this:

DAO

public class ConfiguraFirebase<T> {
    private static DatabaseReference reference = null;
    private static FirebaseStorage storage = null;

    public static DatabaseReference getNoRaiz(){
        return FirebaseDatabase.getInstance().getReference();
    }
    public static DatabaseReference getNo(String no){
        return FirebaseDatabase.getInstance().getReference(no);
    }
    public static FirebaseStorage getStorage(){
        return FirebaseStorage.getInstance();
    }
}

Adapter

LinhaConsultaPerguntaAdapter.class

public class LinhaConsultaPerguntaAdapter extends RecyclerView.Adapter<LinhaConsultaPerguntaAdapter.MyViewHolder> {
    Context origem;
    private List<Pergunta> perguntas = new ArrayList<>();

    public LinhaConsultaPerguntaAdapter(Context origem, List<Pergunta> perguntas) {
        this.perguntas = perguntas;
        this.origem = origem;
    }

    private void flatten(List<Pergunta> perguntas) {
        for (Pergunta pergunta : perguntas) {
            perguntas.add(pergunta);
        }
    }

    @Override
    public int getItemCount() {
        return perguntas.size();
    }

    @Override
    public void onBindViewHolder(@NonNull final LinhaConsultaPerguntaAdapter.MyViewHolder myViewHolder, final int position) {
        Pergunta p = perguntas.get(position);
        myViewHolder.txtDescricao.setText(p.getDescricao());
        myViewHolder.buttonExcluir.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                removeItem(position);
            }
        });
        myViewHolder.buttonEditar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Pergunta pergunta = perguntas.get(position);
                Intent intent = new Intent(origem, EditPergunta.class);
                intent.putExtra("id", pergunta.getId());
                myViewHolder.context.startActivity(intent);
            }
        });
        myViewHolder.btnCadResposta.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Pergunta pergunta = perguntas.get(position);
                Intent intent = new Intent(origem, CadResposta.class);
                intent.putExtra("pergunta", (Parcelable) pergunta);
                myViewHolder.context.startActivity(intent);
            }
        });
        myViewHolder.btnListarRespostas.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Pergunta pergunta = perguntas.get(position);
                Intent intent = new Intent(origem, ListResposta.class);
                intent.putExtra("pergunta", (Parcelable) pergunta);
                myViewHolder.context.startActivity(intent);
            }
        });
    }

    private void removeItem(int position) {
        String mensagem ="Pergunta excluída com sucesso!";
        final Pergunta p = perguntas.get(position);
        final DatabaseReference reference = ConfiguraFirebase.getNo("Pergunta");
        perguntas.remove(position);
        reference.child(p.getId()).removeValue();
        notifyItemRemoved(position);
        notifyItemRangeChanged(position, perguntas.size());
    }

    @NonNull
    @Override
    public LinhaConsultaPerguntaAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View itemList = LayoutInflater.from(viewGroup.getContext()).
                inflate(R.layout.adapter_card_pergunta, viewGroup, false);
        return new MyViewHolder(itemList);
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        Context context;
        TextView txtDescricao;
        Button buttonExcluir;
        Button buttonEditar;
        Button btnCadResposta;
        Button btnListarRespostas;

        public MyViewHolder(View itemView) {
            super(itemView);
            context = itemView.getContext();
            txtDescricao = itemView.findViewById(R.id.txtDescricaoPergunta);
            buttonExcluir = itemView.findViewById(R.id.btnExcluir);
            buttonEditar = itemView.findViewById(R.id.btnEditar);
            btnCadResposta = itemView.findViewById(R.id.btnCadResposta);
            btnListarRespostas = itemView.findViewById(R.id.btnListarRespostas);
        }
    }
}

View

CadPergunta.class

public class CadPergunta extends AppCompatActivity{
    private DatabaseReference reference = ConfiguraFirebase.getNoRaiz();
    Resposta resposta;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cad_pergunta);
        Intent intent = getIntent();
        resposta = intent.getParcelableExtra("resposta");
        Log.d("Position", "Posição =" + resposta);
    }

    public void cadPergunta(View view){
        String descricao = ((EditText)findViewById(R.id.editTextDescricaoPergunta)).getText().toString();

        Pergunta perg = new Pergunta(descricao, resposta);
        DatabaseReference perguntas = reference.child("Pergunta");

        perguntas.push().setValue(perg).addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                Toast.makeText(CadPergunta.this, "Sucesso ao cadastrar pergunta!", Toast.LENGTH_SHORT).show();
                limparCampos();
            }
        })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Toast.makeText(CadPergunta.this, "Erro ao cadastrar pergunta!", Toast.LENGTH_SHORT).show();
                    }
                });
    }
    @SuppressLint("SetTextI18n")
    private void limparCampos(){
        ((EditText)findViewById(R.id.editTextDescricaoPergunta)).setText("Descricao");
    }
}

ListPergunta.class

public class ListPergunta extends AppCompatActivity {
    RecyclerView recyclerViewPergunta;
    private List<Pergunta> perguntas = new ArrayList<>();
    LinhaConsultaPerguntaAdapter myAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_pergunta);
        recyclerViewPergunta = findViewById(R.id.recyclerViewPergunta);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerViewPergunta.setLayoutManager(layoutManager);

        DatabaseReference reference = ConfiguraFirebase.getNo("Pergunta");

        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for(DataSnapshot ds : dataSnapshot.getChildren()) {
                    String id = ds.getKey();
                    String descricao = ds.child("pergunta").getValue(String.class);
                    perguntas.add(new Pergunta(id, descricao));
                }
                myAdapter = new LinhaConsultaPerguntaAdapter(getApplicationContext(), perguntas);
                recyclerViewPergunta.setAdapter(myAdapter);
                recyclerViewPergunta.setHasFixedSize(true);
            }

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

But this is not working right. It's seems like I need to write every single attribute like this.

  • 4
    FYI you can format code by selecting the entire block of code in the editor and using the {} button to automatically indent it all. I did one for you, you could edit the question to do the rest. – Doug Stevenson Mar 12 at 0:40
  • Maybe you need to show us how your firebase database is structured. Then maybe you could convert your entire snapshot to the pojo in your app. Anyway what's not working? – Sergio Mar 12 at 2:51
0

If you want to get nested values in a Firebase Realtime DB, you can create a nested loop of DataSnapshot. For the example:

for(DataSnapshot snapshot : p0.getChildren()){ //First Child
    for(DataSnapshot endSnapshot : snapshot.getChildren()){ //Second Child
       // You code here
    }
}
  • Oh sorry I forgot to show my list view class. I'm already doing something like that but I think it's not right or I forgot to do something – Stefany Biskup Mar 12 at 1:29
  • If you like my answer, you can accept my answer. Thanks – Naufal Prakoso Mar 12 at 1:33

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.