Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include Firestore Timestamps in Entities #39

Open
elersong opened this issue Jul 13, 2024 · 1 comment
Open

Include Firestore Timestamps in Entities #39

elersong opened this issue Jul 13, 2024 · 1 comment
Labels
enhancement New feature or request from_willyovale An issue described in original project, but never implemented

Comments

@elersong
Copy link
Owner

Description

When using the Firestore admin SDK, we can retrieve document timestamps (createTime, updateTime, readTime). These timestamps are useful for backend applications that utilize Firestore. This proposal suggests including these timestamps in Fireorm entities, allowing users to automatically access them without manual creation.

Steps to Reproduce

  1. Create an entity and save it to Firestore using Fireorm.
  2. Retrieve the entity and attempt to access its timestamps (createTime, updateTime, readTime).

Expected Behavior

Entities should automatically include createTime, updateTime, and readTime properties, populated with the corresponding Firestore document timestamps.

Actual Behavior

Currently, entities do not include these timestamps automatically and require manual creation and management.

Acceptance Criteria

  • Add support for Firestore timestamps (createTime, updateTime, readTime) in entities.
  • Ensure that these properties can be overridden by the user if necessary.
  • Provide TypeScript support for the new properties.
  • Add unit tests to validate the inclusion and correctness of the timestamps.

Additional Context

Proposed API Changes

  1. Add Timestamp Properties to Entities:

    • Modify the entity base class to include createTime, updateTime, and readTime properties.
    class BaseEntity {
      id: string;
      createTime?: Date;
      updateTime?: Date;
      readTime?: Date;
    }
  2. Update Repository Methods:

    • Update repository methods to populate these properties from Firestore document metadata.
    class BaseFirestoreRepository<T extends BaseEntity> {
      private extractTFromDocSnap(docSnap: DocumentSnapshot): T {
        const entity = docSnap.data() as T;
        entity.createTime = docSnap.createTime?.toDate();
        entity.updateTime = docSnap.updateTime?.toDate();
        entity.readTime = docSnap.readTime?.toDate();
        return entity;
      }
    
      async findById(id: string): Promise<T | null> {
        const docSnap = await this.firestoreColRef.doc(id).get();
        return docSnap.exists ? this.extractTFromDocSnap(docSnap) : null;
      }
    }
  3. Provide TypeScript Support:

    • Add a Timestamped wrapper to add typing for the new properties.
    export type Timestamped<T> = T & {
      createTime: Date;
      updateTime: Date;
      readTime: Date;
    };
  4. Unit Tests:

    • Add unit tests to validate the inclusion and correctness of the timestamps.
    test('should include Firestore timestamps in entities', async () => {
      const todoRepository = getRepository(Todo);
      const todo = new Todo();
      todo.text = "Check fireorm's Github Repository";
      todo.done = false;
    
      const createdTodo = await todoRepository.create(todo);
      const retrievedTodo = await todoRepository.findById(createdTodo.id);
    
      expect(retrievedTodo).not.toBeNull();
      expect(retrievedTodo.createTime).toBeInstanceOf(Date);
      expect(retrievedTodo.updateTime).toBeInstanceOf(Date);
      expect(retrievedTodo.readTime).toBeInstanceOf(Date);
    });

Example Implementation

import { Collection, getRepository } from 'fireorm';

@Collection()
class Todo extends BaseEntity {
  text: string;
  done: boolean;
}

const todoRepository = getRepository(Todo);

const todo = new Todo();
todo.text = "Check fireorm's Github Repository";
todo.done = false;

const todoDocument = await todoRepository.create(todo); // Create todo

const mySuperTodoDocument = await todoRepository.findById(todoDocument.id); // Read todo. Also retrieves createTime, updateTime and readTime from the Firestore DocumentRef

console.log(mySuperTodoDocument.createTime); // Output: 2022-12-17 00:00:00
console.log(mySuperTodoDocument.updateTime); // Output: 2022-12-17 00:00:00
console.log(mySuperTodoDocument.readTime); // Output: 2022-12-17 00:00:01

Original Issue

@elersong elersong added enhancement New feature or request from_willyovale An issue described in original project, but never implemented labels Jul 13, 2024
@elersong
Copy link
Owner Author

Potentially connected to #35

  • gelouko's Issue (Dec 17, 2022): Proposes including Firestore document timestamps (createTime, updateTime, readTime) in entities.
  • kenchan0130's Issue (Mar 18, 2022): Discusses compatibility issues with Timestamp objects in firebase-admin SDK v11.11.1, which indirectly relates to handling Firestore timestamps correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request from_willyovale An issue described in original project, but never implemented
Projects
None yet
Development

No branches or pull requests

1 participant