Problem
I hope that someone can help me since I have spent the whole day on this, I try to read data from Firebase, I have already done write operations against the database, but I can not access the same data that I registered, I have the following rules in the database:
Rules at the time of the problem
{
"rules": {
"perfiles":{
".read": "auth != null",
".write": "auth != null"
}
}
}
Rules optimization
The optimization that occurred is to increase one more level of control to guarantee that the logged-in user has access only to his information node and not to other users (suggestion of @Franco in his comments).
{
"rules": {
"perfiles":{
"$uid":{
".read": "auth.uid === $uid",
".write": "auth.uid === $uid"
}
}
}
}
With the problem
And the next code in a fragment
baseDatos = FirebaseDatabase.getInstance();
perfilesReferencia = baseDatos.getReference("perfiles");
vista = inflater.inflate(R.layout.fragment_perfil, container, false);
// se obtiene al usuario logueado
usuarioLogueado = FirebaseAuth.getInstance().getCurrentUser();
Query consulta = perfilesReferencia.orderByChild("correo").equalTo(usuarioLogueado.getEmail());
consulta.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot ds) {
Perfil perfilEncontrado = ds.getValue(Perfil.class);
Toast.makeText(getContext(),perfilEncontrado.getCorreo(),Toast.LENGTH_LONG).show();
cedulaET.setText(perfilEncontrado.getCedula());
nombresET.setText(perfilEncontrado.getNombres());
apellidosET.setText(perfilEncontrado.getApellidos());
nacimientoET.setText(perfilEncontrado.getNacimiento());
whatsappET.setText(perfilEncontrado.getWhatsapp());
direccionET.setText(perfilEncontrado.getDireccion());
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(getContext(),"No se ha encontrado el perfil",Toast.LENGTH_LONG).show();
}
});
Code Optimization
Basically what was improved in this code is not to ask in the query by the logged user's mail, but a modification when registering the profile and not using a random key, but the user's uid and in the query to work with this uid (another suggestion from @Franco).
public void verificaPerfil(View view) {
Query consulta = perfilesReferencia.child(usuarioLogueado.getUid());
consulta.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot ds) {
if(ds.exists()){
Perfil perfilEncontrado = ds.getValue(Perfil.class);
Toast.makeText(getContext(),perfilEncontrado.getCorreo(),Toast.LENGTH_LONG).show();
cedulaET.setText(perfilEncontrado.getCedula());
nombresET.setText(perfilEncontrado.getNombres());
apellidosET.setText(perfilEncontrado.getApellidos());
nacimientoET.setText(perfilEncontrado.getNacimiento());
whatsappET.setText(perfilEncontrado.getWhatsapp());
direccionET.setText(perfilEncontrado.getDireccion());
} else {
Toast.makeText(getContext(),"Aún no ha ingresado los datos de su perfil",Toast.LENGTH_LONG).show();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(getContext(),"Ocurrió un error en la ejecución",Toast.LENGTH_LONG).show();
}
});
return;
}
Structure with the problem
The structure uses in this case a random key obtained through a database method:
{
"perfiles" : {
"-LReGzJ4jtu1pCfHqsGa" : {
"apellidos" : "Jaramillo",
"cedula" : "0103780835",
"correo" : "[email protected]",
"direccion" : "Salvador Allende",
"nacimiento" : "5/3/1983",
"nombres" : "Andres",
"whatsapp" : "0984228708"
}
}
}
Optimization of structures
In this case the only change was to register the data with the user's login, (One more suggestion from @Franco).
{
"perfiles" : {
"-LReGzJ4jtu1pCfHqsGa" : {
"apellidos" : "Jaramillo",
"cedula" : "0103780835",
"correo" : "[email protected]",
"direccion" : "Salvador Allende",
"nacimiento" : "5/3/1983",
"nombres" : "Andres",
"whatsapp" : "0984228708"
}
}
}
Up to here optimizations that came in favor of a better functioning of the application.
SOLUTION
The code even without the optimizations was functionally correct and it was not the reason why the information in the database could not be recovered, the problem was that the Profile class did not contemplate the constructor without arguments and only the constructor with arguments and this was what prevented the recovery of the data from the database.