Skip to content

Cannot filter _deleted items with Datastore syncExpression  #14043

@richstimson

Description

@richstimson

Before opening, please confirm:

JavaScript Framework

React Native

Amplify APIs

GraphQL API, DataStore

Amplify Version

v6

Amplify Categories

storage, api

Backend

Amplify CLI

Environment information

# Put output below this line
  System:
    OS: macOS 14.5
    CPU: (8) arm64 Apple M2
    Memory: 84.27 MB / 8.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.12.0 - /usr/local/bin/node
    npm: 10.5.0 - /usr/local/bin/npm
    Watchman: 2024.11.11.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 131.0.6778.86
    Safari: 17.5
  npmPackages:
    @aws-amplify/react-native: ^1.1.6 => 1.1.6 
    @aws-amplify/rtn-push-notification: ^1.2.31 => 1.2.31 
    @aws-amplify/ui-react-native: ^2.2.13 => 2.2.13 
    @aws-sdk/client-cognito-identity-provider: ^3.677.0 => 3.677.0 
    @aws-sdk/client-location: ^3.665.0 => 3.665.0 
    @aws-sdk/client-sns: ^3.696.0 => 3.696.0 
    @aws-sdk/credential-providers: ^3.678.0 => 3.678.0 
    @babel/core: ^7.20.0 => 7.25.7 
    @expo/vector-icons: ^14.0.2 => 14.0.4 
    @react-native-async-storage/async-storage: ^2.0.0 => 2.0.0 
    @react-native-community/netinfo: ^11.4.1 => 11.4.1 
    @react-navigation/native: ^6.0.2 => 6.1.18 
    @types/jest: ^29.5.12 => 29.5.13 
    @types/react: ~18.2.45 => 18.2.79 
    @types/react-native-push-notification: ^8.1.4 => 8.1.4 
    @types/react-test-renderer: ^18.0.7 => 18.3.0 
    HelloWorld:  0.0.1 
    aws-amplify: ^6.6.4 => 6.6.4 
    aws-amplify/adapter-core:  undefined ()
    aws-amplify/analytics:  undefined ()
    aws-amplify/analytics/kinesis:  undefined ()
    aws-amplify/analytics/kinesis-firehose:  undefined ()
    aws-amplify/analytics/personalize:  undefined ()
    aws-amplify/analytics/pinpoint:  undefined ()
    aws-amplify/api:  undefined ()
    aws-amplify/api/server:  undefined ()
    aws-amplify/auth:  undefined ()
    aws-amplify/auth/cognito:  undefined ()
    aws-amplify/auth/cognito/server:  undefined ()
    aws-amplify/auth/enable-oauth-listener:  undefined ()
    aws-amplify/auth/server:  undefined ()
    aws-amplify/data:  undefined ()
    aws-amplify/data/server:  undefined ()
    aws-amplify/datastore:  undefined ()
    aws-amplify/in-app-messaging:  undefined ()
    aws-amplify/in-app-messaging/pinpoint:  undefined ()
    aws-amplify/push-notifications:  undefined ()
    aws-amplify/push-notifications/pinpoint:  undefined ()
    aws-amplify/storage:  undefined ()
    aws-amplify/storage/s3:  undefined ()
    aws-amplify/storage/s3/server:  undefined ()
    aws-amplify/storage/server:  undefined ()
    aws-amplify/utils:  undefined ()
    blob-polyfill: ^9.0.20240710 => 9.0.20240710 
    expo: ~51.0.28 => 51.0.36 
    expo-constants: ~16.0.2 => 16.0.2 
    expo-dev-client: ~4.0.27 => 4.0.27 
    expo-font: ~12.0.9 => 12.0.10 
    expo-linking: ~6.3.1 => 6.3.1 
    expo-location: ^17.0.1 => 17.0.1 
    expo-router: ~3.5.23 => 3.5.23 
    expo-splash-screen: ~0.27.5 => 0.27.6 (0.27.5)
    expo-status-bar: ~1.12.1 => 1.12.1 
    expo-system-ui: ~3.0.7 => 3.0.7 
    expo-web-browser: ~13.0.3 => 13.0.3 
    jest: ^29.2.1 => 29.7.0 
    jest-expo: ~51.0.3 => 51.0.4 
    react: 18.2.0 => 18.2.0 
    react-dom: 18.2.0 => 18.2.0 
    react-native: 0.74.5 => 0.74.5 
    react-native-gesture-handler: ~2.16.1 => 2.16.2 
    react-native-get-random-values: ^1.11.0 => 1.11.0 
    react-native-maps: ^1.18.0 => 1.18.0 
    react-native-paper: ^5.12.5 => 5.12.5 
    react-native-push-notification: ^8.1.1 => 8.1.1 
    react-native-reanimated: ~3.10.1 => 3.10.1 
    react-native-safe-area-context: 4.10.5 => 4.10.5 
    react-native-screens: 3.31.1 => 3.31.1 
    react-native-web: ~0.19.10 => 0.19.12 
    react-test-renderer: 18.2.0 => 18.2.0 
    typescript: ~5.3.3 => 5.3.3 
  npmGlobalPackages:
    @aws-amplify/cli: 12.13.1
    corepack: 0.25.2
    expo-cli: 6.3.10
    npm-check-updates: 17.1.0
    npm: 10.5.0

Describe the bug

I want to hard delete items from a backend amplify @model generated DynamoDB table which is linked to Datastore client on the my frontend mobile app. I don't think this is possible without accessing Dynamo DB directly from a lambda - and this could cause sync issues with Datastore.

If this is correct, then my next option is filter on the _deleted flag so that the deleted items are never received in my local datastore in my observeQuery.

However, when I try to do this:

// Configure DataStore to exclude deleted items
DataStore.configure({
  syncExpressions: [
    syncExpression(GeofenceEvent, () => {
      return (geofenceEvent) => geofenceEvent._deleted.ne(true);
    }),
  ],
});

I get the error: Property '_deleted' does not exist on type 'V5ModelPredicate'.

If I try to add _deleted to the schema, I get: type ModelGeofenceEventFilterInput has already a field with name _deleted.

How do I access the _deleted flag in syncExpression? Is it possible and if not - what other options do I have?

Expected behavior

Items should be filtered from observeQuery if the _deleted flag is set, and syncExpression is configured to filter these items out.

Reproduction steps

Add this code to a datastore with the above schema

// Configure DataStore to exclude deleted items
DataStore.configure({
  syncExpressions: [
    syncExpression(GeofenceEvent, () => {
      return (geofenceEvent) => geofenceEvent._deleted.ne(true);
    }),
  ],
});

Code Snippet

// Put your code below this line.
Schema & observeQuery code below for reference:

schema.graphql
type GeofenceEvent
  @model
  @auth(
    rules: [
      {
        allow: public
        provider: identityPool
        operations: [create, update, delete, read]
      }
      {
        allow: private
        provider: userPools
        operations: [create, update, delete, read]
      }
      {
        allow: public
        provider: apiKey
        operations: [create, update, delete, read]
      }
    ]
  ) {
  GeofenceName: String! @primaryKey(sortKeyFields: ["DeviceId"])
  DeviceId: ID!
  EventType: String!
  updatedAt: AWSDateTime!
}

   // Subscribe to changes for a specific geofence
    const subscribeToSpecificGeofenceEventUpdates = (geofenceName: string) => {
      let previousEventTypes: { [key: string]: string } = {};

      DataStore.observeQuery(GeofenceEvent, (ge) =>
        ge.GeofenceName.eq(geofenceName)
      ).subscribe((snapshot) => {
        const { items, isSynced } = snapshot;
        console.log(
          "observeQuery: received for geofence:",
          geofenceName,
          items,
          isSynced
        );
        if (isSynced) {
          // Handle the updated geofence events
          items.forEach((event) => {
            // console.log(`Device ${event.DeviceId} has event type: ${event.EventType}`);
            const previousEventType = previousEventTypes[event.DeviceId]; // TO DO - should I be using previousEventType store??
            if (previousEventType !== event.EventType) {
              console.log(
                `>>>>>>>>>>>>>>>>>>>>> Device ${event.DeviceId} has NEW event type: ${event.EventType}`
              );
              // Update the previous event type for the device
              previousEventTypes[event.DeviceId] = event.EventType;
            }
          }); 
        }       }); 
    }; 
  }

Log output

// Put your logs below this line
Property '_deleted' does not exist on type 'V5ModelPredicate<LazyGeofenceEvent>'.

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    DataStoreRelated to DataStore category

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions