Shopify / shopify-app-template-remix

287 stars 117 forks source link

How to integrate MongoDB #285

Open ali-faiz-brainx opened 11 months ago

ali-faiz-brainx commented 11 months ago

I want to integrate Mongodb WIth Current Remix template. But after some testing i found that this template try to create the following table. { id, shop, state, isOnline, scope, expires, accessToken, userId } And if I want to make the id as mongoId using @id @map("_id") then Mongo throws error as Shopify tries to store offline_store_name and Mongo throw error here. I also try to add an extra field like mongoId for _id field but shopify don't provide any extra field for this.

Please provide some workaround for this.

Thanks

mason2205 commented 10 months ago

I have same error like this. Do any want know the way to fix this?

maneko00 commented 10 months ago

I have same error like this.

benkissi commented 10 months ago

The problem is mapping idto _id means mongo is going to auto set that field with an objectId, but the template is structured to set the id field with session.id. Follow the steps below to setup mongo.

  1. Map a different field in the schema to _id
    
    generator client {
    provider = "prisma-client-js"
    }

datasource db { provider = "mongodb" url = env("MONGODB_URI") }

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


In my case I created a field called `session_id` and mapped that to the default objectId that mongo is going generate

2. You have to update the `predev` command in package.json. Since mongo is not a relational database the migrate command is going to fail. So to sync the schema with the db you can run  `npx prisma db push` or add it the predev command in package.json scripts.

. . . "scripts": { "build": "NODE_ENV=production remix build", "predev": "prisma generate && prisma db push", . . .


3. When you try to run the app at this point, you might get this error.
`prisma needs to perform transactions, which requires your mongodb server to be run as a replica set`. This means you need to setup your local mongo environment to run like a replica set. You can read more about the issue here and see various ways to make your local mongo server do that. [Mongo Replica Set Issue](https://github.com/prisma/prisma/issues/8266)

The simplest solution which is what I used is Mongodb Atlas.

4. Create an account on [Mongodb Atlas](https://www.mongodb.com/atlas/database) and create a free cluster. Their clusters are configured by default as replica sets. Get the connection string from the cluster and paste that in your .env file (.env file should be in root of project)
eg:

MONGODB_URI="mongodb+srv://username>:<password>@cluster0.msjsks.mongodb.net/<yourdbname"

Replace the username and password part in the connection url. Remember to put whatever name you want to use for your db at the end of the connection url.

4. If your shopify app is already running, stop and start it again.

These are the steps I took to get it working.

When session is stored you will have 2 id fields

{ _id: ObjectId(xxxxxxxxxxx), id: "example-test-store.myshopify.com", . . . }

ali-faiz-brainx commented 10 months ago

Thanks @benkissi will surely try this.

alexislepresle commented 10 months ago

I had the same problem. Thanks @benkissi , problem solved 👍

mumarse commented 10 months ago

I am getting this error when i connect mongodb anyone have solution ?

Prisma schema loaded from prisma\schema.prisma

✔ Generated Prisma Client (4.16.2 | library) to .\node_modules\@prisma\client in 87ms
You can now start using Prisma Client in your code. Reference: https://pris.ly/d/client

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()

Prisma schema loaded from prisma\schema.prisma Datasource "db": MongoDB database "remix" at "0.0.0.0:27017" Error: MongoDB error Server selection timeout: No available servers. Topology: { Type: Unknown, Servers: [ { Address: 0.0.0.0:27017, Type: Unknown, Error: The requested address is not valid in its context. (os error 10049) }, ] } 0: schema_core::commands::schema_push::Calculate from at schema-engine\core\src\commands\schema_push.rs:43 1: schema_core::state::SchemaPush at schema-engine\core\src\state.rs:433

ali-faiz-brainx commented 10 months ago

Hi @mumarse are you using local Mongodb or cloud? Your error shows that you are trying to use local MongoDB. I think you need to install MongoDB locally. But that does not work for you either. Prisma only supports MongoDB instance that supports replica set for the cluster. And local Mongo doesn't support a replica set. So, if you use the MongoDB Atlas cluster that by default provides a replica set for each cluster, it works for you, as working for me.

Here is the code for reference:

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mongodb"
  url      = env("DATABASE_URL")
}

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

Hope this helps.

asrasoft-admin commented 7 months ago

Thank you

adventuretocode commented 7 months ago

The problem is mapping idto _id means mongo is going to auto set that field with an objectId, but the template is structured to set the id field with session.id. Follow the steps below to setup mongo.

  1. Map a different field in the schema to _id
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mongodb"
  url      = env("MONGODB_URI")
}

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

In my case I created a field called session_id and mapped that to the default objectId that mongo is going generate

  1. You have to update the predev command in package.json. Since mongo is not a relational database the migrate command is going to fail. So to sync the schema with the db you can run npx prisma db push or add it the predev command in package.json scripts.
. . .
"scripts": {
    "build": "NODE_ENV=production remix build",
    "predev": "prisma generate && prisma db push",
    . . . 
  1. When you try to run the app at this point, you might get this error. prisma needs to perform transactions, which requires your mongodb server to be run as a replica set. This means you need to setup your local mongo environment to run like a replica set. You can read more about the issue here and see various ways to make your local mongo server do that. Mongo Replica Set Issue

The simplest solution which is what I used is Mongodb Atlas.

  1. Create an account on Mongodb Atlas and create a free cluster. Their clusters are configured by default as replica sets. Get the connection string from the cluster and paste that in your .env file (.env file should be in root of project) eg:
MONGODB_URI="mongodb+srv://<username>:<password>@cluster0.msjsks.mongodb.net/<yourdbname>"

Replace the username and password part in the connection url. Remember to put whatever name you want to use for your db at the end of the connection url.

  1. If your shopify app is already running, stop and start it again.

These are the steps I took to get it working.

When session is stored you will have 2 id fields

{
_id: ObjectId(xxxxxxxxxxx),
id: "example-test-store.myshopify.com",
. . .
}

@benkissi And @alexislepresle step 1 I have creat the new .env file and declare the DATABASE_URL=mongodb+srv://user:pass@cluster0.2xxxxi.mongodb.net/remix

step 2 then change the file

prisma/schema.prisma

` datasource db { provider = "mongodb" url = env("DATABASE_URL") }

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

` step 3 added into the package.json

"build": "NODE_ENV=production remix build", "predev": "prisma generate && prisma db push",

**step 4 **
run the command for the 

`npm run predev ` 

**output**

The database is already in sync with the Prisma schema.

✔ Generated Prisma Client (4.16.2 | library) to ./node_modules/@prisma/client in 67ms

    **step 5 **
    Run the command for the app in dev mode.

Error output

Screenshot from 2023-11-22 15-41-37

ridoystarlord commented 7 months ago

Thanks @benkissi

benkissi commented 7 months ago

The problem is mapping idto _id means mongo is going to auto set that field with an objectId, but the template is structured to set the id field with session.id. Follow the steps below to setup mongo.

  1. Map a different field in the schema to _id
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mongodb"
  url      = env("MONGODB_URI")
}

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

In my case I created a field called session_id and mapped that to the default objectId that mongo is going generate

  1. You have to update the predev command in package.json. Since mongo is not a relational database the migrate command is going to fail. So to sync the schema with the db you can run npx prisma db push or add it the predev command in package.json scripts.
. . .
"scripts": {
    "build": "NODE_ENV=production remix build",
    "predev": "prisma generate && prisma db push",
    . . . 
  1. When you try to run the app at this point, you might get this error. prisma needs to perform transactions, which requires your mongodb server to be run as a replica set. This means you need to setup your local mongo environment to run like a replica set. You can read more about the issue here and see various ways to make your local mongo server do that. Mongo Replica Set Issue

The simplest solution which is what I used is Mongodb Atlas.

  1. Create an account on Mongodb Atlas and create a free cluster. Their clusters are configured by default as replica sets. Get the connection string from the cluster and paste that in your .env file (.env file should be in root of project) eg:
MONGODB_URI="mongodb+srv://<username>:<password>@cluster0.msjsks.mongodb.net/<yourdbname>"

Replace the username and password part in the connection url. Remember to put whatever name you want to use for your db at the end of the connection url.

  1. If your shopify app is already running, stop and start it again.

These are the steps I took to get it working.

When session is stored you will have 2 id fields

{
_id: ObjectId(xxxxxxxxxxx),
id: "example-test-store.myshopify.com",
. . .
}

@benkissi And @alexislepresle step 1 I have creat the new .env file and declare the DATABASE_URL=mongodb+srv://user:pass@cluster0.2xxxxi.mongodb.net/remix

step 2 then change the file

prisma/schema.prisma

` datasource db { provider = "mongodb" url = env("DATABASE_URL") }

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

` step 3 added into the package.json

"build": "NODE_ENV=production remix build", "predev": "prisma generate && prisma db push",

**step 4 **
run the command for the 

`npm run predev ` 

**output**

The database is already in sync with the Prisma schema.

✔ Generated Prisma Client (4.16.2 | library) to ./node_modules/@prisma/client in 67ms

    **step 5 **
    Run the command for the app in dev mode.

Error output

Screenshot from 2023-11-22 15-41-37

Remove the migrations

Lan-Ne commented 5 months ago

It could be useful for someone. I've managed to connect mongo without any Prisma setup. I replaced the session storage adapter with this image

Then removed prisma commands from the Docker file.

The table was created without any schema in the code. image

And, it was successfully hosted on Heroku.

vizardkill commented 3 months ago

Sigue sin funcionar ninguna de las alternativas funciona

tungmzvina commented 3 months ago

Remove the migrations

Thanks @benkissi, I get a "migrate" error. And I don't know how to do the "Remove the migrations". please help

benkissi commented 3 months ago

Remove the migrations

Thanks @benkissi, I get a "migrate" error. And I don't know how to do the "Remove the migrations". please help

Delete any migration files that were generated before

tungmzvina commented 3 months ago

Hi @benkissi Thank you for your help. I followed your instructions on how to delete the migrations folder. But then I get this error when I run npm run dev. Is there any way to fix it. I'm really stuck Screenshot 2024-03-21 225641

benkissi commented 3 months ago

Hi @benkissi Thank you for your help. I followed your instructions on how to delete the migrations folder. But then I get this error when I run npm run dev. Is there any way to fix it. I'm really stuck Screenshot 2024-03-21 225641

You have to update the predev command in package.json. see step 2. Make to delete any migration files in the Prisma folder

ali-faiz-brainx commented 3 months ago

Hi @benkissi please also remove prisma migrate deploy from package.json and npx prisma migrate deploy from shopify.web.toml file and add this line in both places prisma db push. Hopefully this will solve your issue. image

tungmzvina commented 3 months ago

thanks @ali-faiz-brainx & @benkissi . My problem has been solved.

ShubhamConversios commented 1 week ago

It could be useful for someone. I've managed to connect mongo without any Prisma setup. I replaced the session storage adapter with this image

Then removed prisma commands from the Docker file.

The table was created without any schema in the code. image

And, it was successfully hosted on Heroku.

how can make relation thesession storage with user