To maintain parity between the request-response and real time capabilities of Firestore, we use AWS AppSync, a real time, managed GraphQL service that decouples the integration layer to arbitrary backend data sources by way of resolvers. You can think of a resolver as a mechanism to acquire the data needed to hydrate a frontend GraphQL model.
Resolvers are extremely flexible and can be defined all the way down to individual fields in model definitions. Resolvers can leverage several different data sources at once, including databases, REST APIs, and arbitrary Lambda Functions. Resolvers can also be pipelined so multiple refinements of model abstractions can be sequenced.
You can see in our architecture that we use a single Lambda resolver to integrate with DynamoDB. This Lambda Function implements the low level create, read, update, and delete (CRUD) operations using the DynamoDB SDK.
AppSync also supports real time subscriptions via GraphQL, so where we were using Firestore listeners, we can migrate to AppSync subscriptions.