Luka Špoljarić
Luka Špoljarić

Reputation: 999

Firestore google.cloud.Timestamp parsing

When i receive firestore DocumentSnapshot field(which is timestamp) with:

DocumentSnapshot snapshot = message.getPayload().getDocumentSnapshot();
Object o = snapshot.get("fieldName);

everything works fine and Object o is instantiated with real data Thu Jan 10 00:00:00 CET 2019

But when i try to receive the field as google.cloud.Timestamp:

DocumentSnapshot snapshot = message.getPayload().getDocumentSnapshot();
Timestamp ts = snapshot.getTimestamp("fieldName");

or Timestamp ts = (Timestamp) snapshot.get("fieldName"); it fails with error java.util.Date cannot be cast to com.google.cloud.Timestamp

Could someone clarify this behavior and how should i access ad retrieve google.cloud.Timestamp object from DocumentSnapshot? Im having this problem only with Timestamp object, every other type parses normally.

EDIT, adding more code:

Accessing firestore:

    @Bean
    public FirestoreGateway registerFirestoreGateway(FirestoreGatewayProperties properties) throws IOException {
        Resource resource = new ClassPathResource(properties.getFirestoreConfiguration());
        InputStream configuration = resource.getInputStream();

        FirebaseOptions options = new FirebaseOptions.Builder()
                .setCredentials(GoogleCredentials.fromStream(configuration))
                .setDatabaseUrl(properties.getDatabaseUrl())
                .build();
        FirebaseApp.initializeApp(options);

        return new FirestoreGateway(FirestoreClient.getFirestore());
    }

Firestore snapshot listener:

@EventListener(ApplicationReadyEvent.class)
public void listenToRequestCommands() {
    firestoreConnection.listCollections().forEach(collectionReference -> {
        collectionReference
                .document(properties.getFirestoreCommand())
                .addSnapshotListener((snapshot, e) -> {
                            Object o = snapshot.get("timestamp");
                            Timestamp ts = (Timestamp) snapshot.get("timestamp");
                        }
                );
    });
}

Object o parses normally to right value, while Timestamp ts for the same event throws "java.util.Date cannot be cast to com.google.cloud.Timestamp"

Timestamp field definition in database:

enter image description here

Upvotes: 0

Views: 3644

Answers (2)

Java wanna bee
Java wanna bee

Reputation: 3099

Kotlin solution that work for me:

val timestamp: Date = document.getDate("timestamp") as Date

Upvotes: 1

Alex Mamo
Alex Mamo

Reputation: 138804

You are getting the following error:

java.util.Date cannot be cast to com.google.cloud.Timestamp

Because in your database the timestamp property is of type Date and not Timestamp. There is no way in Java to cast an object of type Date to an object of type com.google.firebase.Timestamp because there is no inheritance relationship between them.

To solve this, you need to get that property as Date, using the following line of code:

Date timestamp = snapshot.getDate("timestamp");

Edit:

When you are setting a field to be of type timestamp, you are setting it as Timestamp, which is apart of another package. See, class Timestamp extends Date. So a timestamp object is-a Date, because it inherits from the Date class.

As a conclusion, the Timestamp class from the com.google.firebase package is different from the Timestamp class from the java.sql package, which in terms is different from the Timestamp class that exists within java.security package.

Edit2:

According to your comment, when using:

(java.util.Date) snapshot.get("timestamp");

It means that the object that is returned by snapshot.get("timestamp") is casted to Date, which basically is the same thing. With other words, you tell the compiler that whatever the object that is returned, consider it a Date object. And it works because the type of your property in the database is Date and not Firebase Timestamp.

Upvotes: 1

Related Questions