Shopify / shopify-app-js

MIT License
286 stars 113 forks source link

Prisma / MongoDB for Session Storage - can't handle id #488

Closed dopla-dev closed 11 months ago

dopla-dev commented 11 months ago

Issue summary

I'm attempting to use MongoDB Atlas as the db to handle session storage via Prisma. But I'm struggling with an apparent conflict between the way that 'id' is handled in the prisma model / @shopify/shopify-app-session-storage-prisma.

When using MongoDB, Prisma requires the id to @map("_id"). From the Prisma docs:

"The MongoDB connector has specific rules for defining an ID field that differs from relational databases. An ID must be defined by a single field using the @id attribute and must include @map("_id")."

However, this causes a conflict when attempting to store a session in the table, because the id (e.g. offline_dopla-dev.myshopify.com) is not a field that should be upserted (and I think also because it is not an objectId).

"@shopify/app": "3.50.2", "@shopify/shopify-app-session-storage-prisma": "^2.0.0"


// Paste any relevant logs here

07:45:36 │ remix │ [shopify-api/INFO] Creating new session | {shop: dopla-dev.myshopify.com,       
isOnline: false}
07:45:36 │ remix │ [shopify-app/ERROR] Error during OAuth callback | {error:
07:45:36 │ remix │ Invalid `this.getSessionTable().upsert()` invocation in
07:45:36 │ remix │ C:\**\node_modules\@s
hopify\shopify-app-session-storage-prisma\build\cjs\prisma.js:27:34
07:45:36 │ remix │
07:45:36 │ remix │   24 async storeSession(session) {
07:45:36 │ remix │   25   await this.ready;
07:45:36 │ remix │   26   const data = this.sessionToRow(session);
07:45:36 │ remix │ → 27   await this.getSessionTable().upsert({
07:45:36 │ remix │          where: {
07:45:36 │ remix │            id: 'offline_dopla-dev.myshopify.com'
07:45:36 │ remix │          },
07:45:36 │ remix │          update: {
07:45:36 │ remix │            id: 'offline_dopla-dev.myshopify.com',
07:45:36 │ remix │            ~~
07:45:36 │ remix │            shop: 'dopla-dev.myshopify.com',
07:45:36 │ remix │            state: '187155718173001',
07:45:36 │ remix │            isOnline: false,
07:45:36 │ remix │            scope: 'write_products',
07:45:36 │ remix │            expires: null,
07:45:36 │ remix │            accessToken: 'shpua_1c8996ecffa1eb779973d0f60b55f7a3',
07:45:36 │ remix │            userId: null
07:45:36 │ remix │          },
07:45:36 │ remix │          create: {
07:45:36 │ remix │            id: 'offline_dopla-dev.myshopify.com',
07:45:36 │ remix │            shop: 'dopla-dev.myshopify.com',
07:45:36 │ remix │            state: '187155718173001',
07:45:36 │ remix │            isOnline: false,
07:45:36 │ remix │            scope: 'write_products',
07:45:36 │ remix │            expires: null,
07:45:36 │ remix │            accessToken: 'shpua_1c8996ecffa1eb779973d0f60b55f7a3',
07:45:36 │ remix │            userId: null
07:45:36 │ remix │          }
07:45:36 │ remix │        })
07:45:36 │ remix │
07:45:36 │ remix │ Unknown arg `id` in update.id for type SessionUpdateInput. Available args:      
07:45:36 │ remix │
07:45:36 │ remix │ type SessionUpdateInput {
07:45:36 │ remix │   shop?: String | StringFieldUpdateOperationsInput
07:45:36 │ remix │   state?: String | StringFieldUpdateOperationsInput
07:45:36 │ remix │   isOnline?: Boolean | BoolFieldUpdateOperationsInput
07:45:36 │ remix │   scope?: String | NullableStringFieldUpdateOperationsInput | Null
07:45:36 │ remix │   expires?: DateTime | NullableDateTimeFieldUpdateOperationsInput | Null        
07:45:36 │ remix │   accessToken?: String | StringFieldUpdateOperationsInput
07:45:36 │ remix │   userId?: BigInt | NullableBigIntFieldUpdateOperationsInput | Null
07:45:36 │ remix │ }
07:45:36 │ remix │
07:45:36 │ remix │ }
07:45:36 │ remix │ GET /auth/callback?code=16a3b665b27f2da244f146e9cc99e0a4&hmac=9bc56d6fa633c0adbc
10cfbcda6a0cc713d78ee3e80e87f4a95caf9c8645e0c5&host=YWRtaW4uc2hvcGlmeS5jb20vc3RvcmUvZG9wbGEtZGV2&sh
op=dopla-dev.myshopify.com&state=187155718173001&timestamp=1699775137 500 - - 419.269 ms

## Expected behavior

The session data should upsert into the db, without trying to mutate the _id field.

## Actual behavior

The error above.

## Steps to reproduce the problem

1. In the Prisma schema, update the datasource to a MongoDB db
2. In the Prisma schema, update the session model to map("_id"), as required by prisma

model Session {
  id          String     @id @map("_id")
  shop        String
  state       String
  isOnline    Boolean   @default(false)
  scope       String?
  expires     DateTime?
  accessToken String
  userId      BigInt?
}

3. Inside package.json remove prisma migrate commands (not compatible with mongoDB)
4. Manually init a 'Session' db on MongoDB Atlas
5. npm run dev
6. Install app on dev store
thunkr commented 11 months ago

Hi, hope you are well, the same problem here https://prnt.sc/0wE_0QclIszC are you able to solve this ?

dopla-dev commented 11 months ago

Hi, hope you are well, the same problem here

https://prnt.sc/0wE_0QclIszC

are you able to solve this ?

I just found this, I haven't implemented it yet but looks like a good workaround:

https://github.com/Shopify/shopify-app-template-remix/issues/285