Attempting to update a Fireorm object containing a map of custom objects results in a serialization error. Firestore does not support JavaScript objects with custom prototypes, leading to issues when saving such objects.
Steps to Reproduce
Create a Fireorm model containing a map of custom objects.
Attempt to update an instance of this model in Firestore.
Observe the serialization error.
Expected Behavior
The update should serialize the custom objects correctly and save them to Firestore without errors.
Actual Behavior
A serialization error occurs, stating that Firestore does not support JavaScript objects with custom prototypes.
Acceptance Criteria
Implement a mechanism to serialize objects with custom prototypes to plain objects before saving to Firestore.
Ensure compatibility with Fireorm's existing functionality.
Add unit tests to validate the correct serialization of complex data types.
Additional Context
May 25, 2021: Initial issue raised about the serialization error.
May 30, 2021: Discussion about potential fixes and workarounds, including using a helper function to convert objects to plain objects.
May 30, 2021: Suggestion to use a helper function to clean objects of references and prototypes.
Proposed API Changes
Serialize Entities to Plain Objects:
Implement a mechanism to serialize entities to plain objects before saving to Firestore.
import { plainToClass, classToPlain } from 'class-transformer';
async function saveEntity(entity: any) {
const plainObject = classToPlain(entity);
await firestore.collection('collectionName').add(plainObject);
}
Support for Custom Prototypes:
Ensure the serialization mechanism supports custom prototypes and complex data types.
class AuthData {
id = "";
email = "";
displayName = "";
emailVerified = false;
}
@Collection("users")
class User {
id = "";
@Type(() => AuthData)
authData? = new AuthData();
}
const userRepository = getRepository(User);
const user = new User();
user.id = "user123";
user.authData = new AuthData();
user.authData.email = "test@example.com";
saveEntity(user);
Helper Function:
Provide a helper function to convert objects to plain objects before saving to Firestore.
function plainObject(obj: any): any {
return JSON.parse(JSON.stringify(obj));
}
// Example usage
const user = new User();
user.id = "user123";
user.authData = new AuthData();
user.authData.email = "test@example.com";
userRepository.update(plainObject(user));
Unit Tests:
Add unit tests to validate the serialization of complex data types with custom prototypes.
test('should serialize complex data types to plain objects', async () => {
const user = new User();
user.id = "user123";
user.authData = new AuthData();
user.authData.email = "test@example.com";
const plainUser = plainObject(user);
expect(plainUser.authData.email).toBe("test@example.com");
});
Example Implementation
class AuthData {
id = "";
email = "";
displayName = "";
emailVerified = false;
}
@Collection("users")
class User {
id = "";
@Type(() => AuthData)
authData? = new AuthData();
}
const userRepository = getRepository(User);
const user = new User();
user.id = "user123";
user.authData = new AuthData();
user.authData.email = "test@example.com";
userRepository.update(plainObject(user));
Description
Attempting to update a Fireorm object containing a map of custom objects results in a serialization error. Firestore does not support JavaScript objects with custom prototypes, leading to issues when saving such objects.
Steps to Reproduce
Expected Behavior
The update should serialize the custom objects correctly and save them to Firestore without errors.
Actual Behavior
A serialization error occurs, stating that Firestore does not support JavaScript objects with custom prototypes.
Acceptance Criteria
Additional Context
Proposed API Changes
Serialize Entities to Plain Objects:
Support for Custom Prototypes:
Helper Function:
Unit Tests:
Example Implementation
Original Issue