skip to Main Content

I have a database that has a structure to this. I’ve updated the values clearly, but the idea remains. I’m trying to essentially find the refresh token and update it with a new token. Here is the database structure sample

{
  "_id": "xxxxxxxxxxxxxxxxx",
  "username": "[email protected]",
  "refreshTokens": [
    {
      "refreshToken": "token_example_1",
      "_id": "xxxxxxxxxxxxxxxxx"
    }
  ],
  "salt": "salted_stuff",
  "hash": "hashed_stuff",
  "__v": 1
}

Here is my schema structure

const session = new Schema({
  refreshToken: {
    type: String,
    default: '',
  },
});

const userSchema = new Schema({
  password: String,
  refreshTokens: [session],
});

userSchema.set('toJSON', {
  transform: function (doc, ret, options) {
    delete ret.refreshToken;
    return ret;
  },
});

Now, what I’m trying to do to update it is

User.findOneAndUpdate(
        { _id: userId, refreshTokens: { $elemMatch: { refreshToken: refreshToken } } },
        { $set: { 'refreshTokens.$.refreshToken': newRefreshToken } }
      );

newRefreshToken is built from another function and userId is a variable based off another function of retrieving that internally. Both of those are working as I’ve consoled logged them and can see they are correct.

When I check the database, the refreshToken doesn’t change after running the query.

Am I doing something wrong here? The original user creation and everything works fine so I know the connection is there and it’s not returning any errors. Even this update isn’t returning errors. It’s just not updating the data.

I have scoured multiple other questions and forums. I tried mongoplayground and it seemed to work, so not sure why it’s not actually working.

I’ve also tried

User.updateOne(
        { _id: userId, refreshTokens: { $elemMatch: { refreshToken: refreshToken } } },
        { $set: { 'refreshTokens.$.refreshToken': newRefreshToken } }
      );

and

User.findOneAndUpdate(
        { _id: userId, 'refreshTokens.refreshToken': refreshToken } } },
        { $set: { 'refreshTokens.$.refreshToken': newRefreshToken } }
      );

No success so far. And if I try to do a

.then((user) => {user.save()})

I get an error saying that is not a function.

2

Answers


  1. Chosen as BEST ANSWER

    For anyone else that runs across this with the same issue...

    I ended up having to set the .post as an asyn function and then use .await plus .exec() for the findOneAndUpdate function like below

    router.post('/refreshToken', async (req, res, next) => {
    ...
            await User.findOneAndUpdate(
              {
                _id: userId,
                refreshTokens: {
                  $elemMatch: { refreshToken: refreshToken },
                },
              },
              {
                $set: { 'refreshTokens.$.refreshToken': newRefreshToken },
              }
            )
              .exec()
    ...
    }
    

    This forced the database to update before creating the new cookie and storing the new token.


  2. I notice that you have 2 extra brackets in your original code. The fix is below:

    {
        "_id": "64480569a2c60bc65d10b377",
        "username": "[email protected]",
        "refreshTokens": [
          {
            "refreshToken": "token_example_1",
            "_id": "64480569a2c60bc65d10b37a"
            }
        ],
        "salt": "salted_stuff",
        "hash": "hashed_stuff",
        "__v": 1
      }
      
    

    Maybe instead of

    User.findOneAndUpdate(
            { _id: userId, refreshTokens: { $elemMatch: { refreshToken: refreshToken } } },
            { $set: { 'refreshTokens.$.refreshToken': newRefreshToken } }
          );
    

    You can try:

    User.findOneAndUpdate(
            { _id: userId, "refreshTokens.refreshToken": refreshToken  },
            { $set: { 'refreshTokens.$.refreshToken': newRefreshToken } }
          );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search