Home » Android » android – Accessing data stored as Object in Firestore database

android – Accessing data stored as Object in Firestore database

Posted by: admin June 15, 2020 Leave a comment

Questions:

database structure

Recently I started testing Firebase new document db Firestore for learning purpose, I am stuck right now to access the values store inside the document as object.

I am using the below code to access object Privacy stored in document, but I am not sure how to access the Key - Value? For Example I have 3 sub Key - Value pair in the object, how will I access and edit it individually?

DocumentReference docRef = FirebaseFirestore.getInstance().collection("Users").document("PQ8QUHno6QdPwM89DsVTItrHGWJ3");
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
        if (task.isSuccessful()) {
            DocumentSnapshot document = task.getResult();
            if (document != null) {
                Log.d(TAG, "DocumentSnapshot data: " + task.getResult().getData().get("privacy"));
                Object meta_object = task.getResult().getData().get("privacy");
            } else {
                Log.d(TAG, "No such document");
            }
        } else {
            Log.d(TAG, "get failed with ", task.getException());
        }
    }
});

Any help is appreciated, thanks.

How to&Answers:

The privacy field within your document can be considered a Map<String, Boolean>, so you could cast the value of this field into such a variable:

HashMap<String, Boolean> privacy = (HashMap<String, Boolean>) task.getResult().getData().get("privacy");

Now the main problem with this is that you’ll likely see an “unchecked cast” compiler warning because casting a Map like this is not ideal as you can’t guarantee that the database structure will always contain String : Boolean values in this field.

In this case, I would suggest using custom objects to store & retrieve objects in your database, which will automatically deal with marshalling and casting for you:

DocumentReference docRef = FirebaseFirestore.getInstance().collection("Users").document("PQ8QUHno6QdPwM89DsVTItrHGWJ3");
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
        if (task.isSuccessful()) {
            DocumentSnapshot document = task.getResult();
            if (document != null) {
                User user = task.getResult().toObject(User.class);
            } else {
                Log.d(TAG, "No such document");
            }
        } else {
            Log.d(TAG, "get failed with ", task.getException());
        }
    }
});

Where your User class is something like:

public class User {
    private String username;
    private HashMap<String, Boolean> privacy;

    public User() {}

    public User(String username, HashMap<String, Boolean> privacy) {
        this.username = username;
        this.privacy = privacy;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public HashMap<String, Boolean> getPrivacy() {
        return username;
    }

    public void setPrivacy(HashMap<String, Boolean> privacy) {
        this.privacy = privacy;
    }
}

In this example, the User user = task.getResult().toObject(User.class) call will marshall the entire document into an instance of your User object, and you can then access the privacy map with:

HashMap<String, Boolean> userPrivacy = user.getPrivacy();

Each field in the document will be matched to a field with the same name within your custom object, so you could also add the settings or photo_url fields in the same fashion. You just need to remember:

Each custom class must have a public constructor that takes no arguments. In addition, the class must include a public getter for each property.