Question: I did not quite understand when should I use DatabaseReference and when DataSnapshot.

In my application I seem to be using both of them without real distinction (maybe except for writing to Firebase in which case DataSnapshot was not made for).

Answer: 
A DatabaseReference is a starting point for all database operations. This allows you to read, write, and create new DatabaseReferences.

A DataSnapshot is an efficiently-generated immutable copy of the data at a Firebase Location. They cannot be modified and will never change.

I believe that under the hood, the DataSnapshot would be a more efficient object to create than a DatabaseReference and a safer object to work with in a read-only scenario as this would be an immutable object without any extra data attached to it like the DatabaseReference.

Sources:

DatabaseReference
<https://firebase.google.com/docs/reference/android/com/google/firebase/database/DatabaseReference>

DataSnapshot
<https://firebase.google.com/docs/reference/android/com/google/firebase/database/DataSnapshot>
**DatabaseReference** is used to refer to the location of a specific node in your database structure.
**DataSnapshot** is used to fetch data from the node whenever a listener event is triggered from database. The data is fetched in form of key-value pairs.