Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MongoDB - loopback.getCurrentContext() return null #2519

Closed
dongmai opened this issue Jul 20, 2016 · 11 comments
Closed

MongoDB - loopback.getCurrentContext() return null #2519

dongmai opened this issue Jul 20, 2016 · 11 comments

Comments

@dongmai
Copy link

dongmai commented Jul 20, 2016

Hi everyone ,

Sorry for duplication, but I'm facing it again on nearly the latest version of loopback.
Here is my pacakge.json

{
  "name": "test",
  "version": "1.0.0",
  "main": "server/server.js",
  "scripts": {
    "start": "node .",
    "pretest": "eslint .",
    "posttest": "nsp check"
  },
  "dependencies": {
    "async": "^2.0.0",
    "compression": "^1.0.3",
    "cors": "^2.5.2",
    "helmet": "^1.3.0",
    "loopback": "^2.22.0",
    "loopback-boot": "^2.6.5",
    "loopback-component-explorer": "^2.4.0",
    "loopback-connector-mongodb": "^1.15.2",
    "loopback-datasource-juggler": "^2.39.0",
    "loopback-testing": "^1.2.0",
    "serve-favicon": "^2.0.1"
  },
  "devDependencies": {
    "eslint": "^2.5.3",
    "nsp": "^2.1.0"
  },
  "repository": {
    "type": "",
    "url": ""
  },
  "license": "UNLICENSED",
  "description": "test"
}

I've used a middleware to save current logged user data into context but it (getCurrentContext) always returned null when working with MongoDB (memory db works just fine.)

Bellow is my code,

app.use(loopback.token()); 
app.use(loopback.context());

app.use(function (req, res, next) {
    if (!req.accessToken) return next();

    app.models.User.findById(req.accessToken.userId, function(err, user) {
        if (err)   return next(err);
        if (!user) return next(new Error('No user with this access token was found.'));
        res.locals.currentUser = user;

        var loopbackContext = loopback.getCurrentContext();
        console.log('SERVER CTX?' +loopbackContext);
        if (loopbackContext) {
            loopbackContext.set('currentUser', user);
        }else{
            throw new Error('Current context is null.');
        }
        next();
    });
});

Can anyone please have a look ? Have I done something wrong ?

Thanks.

@0candy
Copy link
Contributor

0candy commented Jul 20, 2016

Thank you for pointing out this issue. Due to the instability, there are plans to deprecate this method.
See #1676

@syuhei176
Copy link

I had same problem, so I use [email protected] . It work fine.

@beornharris
Copy link

beornharris commented Aug 2, 2016

Hey, I've run across this issue as well and just wanted to add some extra info (hope it helps somewhere). I had quick look through #1676 and didnt see anything that might help me.

I initially had an earlier version of loopback running, where I had no problems calling loopback.getCurrentContext() from within a remote method. I inadvertently updated to the current version, and started seeing issues.

I have created a demo repo (from scratch and using slc commands + customisation) to help explain.

https://github.com/beornharris/authtest

The issue I am experiencing is directly related to MongoDB and access tokens, as far as I can tell. Using the repo, the steps to replicate (in api explorer) are as follows (note: requires mongo instance) :

  1. go to endpoint /Networks/{id}/contacts, enter an ID (value irrelevant) and empty object {} and submit. The console shows a context received at the endpoint (from common/models/network.js - Network.addContact)
CONTEXT:  Namespace {
  name: 'loopback',
  active: { accessToken: undefined },
  _set: [ null ],
  id:
   AsyncListener {
     create: [Function],
     flags: 15,
     before: [Function],
     after: [Function],
     error: [Function],
     uid: 2,
     data: null } }
  1. Login using /Accounts/login

`{ "email": "[email protected]", "password": "user1"}

and set the Access Token.

  1. Repeat step 1 - the console shows

CONTEXT: null

Given this, I have a few other observations :

  1. Issue does not occur when using memory DB connector
  2. CONTEXT always shows null when ACL or AccessToken are set to mongo (this may well be by design, but I dont recall reading in the docs that these should ALWAYS be in-memory)
  3. Error also occurs when using the built-in User model, and not just the derived (Account) model.

EDIT: @syuhei176 - I can confirm that the issue disappears with [email protected]

@dongmai
Copy link
Author

dongmai commented Aug 3, 2016

Just try to use [email protected] And it isn't working. :(

@beornharris
Copy link

@dongmai - just to confirm, to downgrade the mongo connector you did something like the following...

  1. change package.json from "^1.15.2" to "1.15.1"
  2. npm install

so it is using 1.15.1, and not minimum 1.15.1 ?

@josieusa
Copy link

josieusa commented Aug 3, 2016

I had the same issue using the same connector.
I solved it using my own PR and Node 6.3.1 locally:
strongloop/loopback-context#2
strongloop/loopback-context#11
So far, so good.
Of course, it's going to need more tests.
I'd also mention that it solved other similar issues with getCurrentContext() for me (see #1495 for examples).
Your mileage may vary

@dongmai
Copy link
Author

dongmai commented Aug 4, 2016

@beornharris Yes, I've downgraded the version number in package json and re-run npm install of course.

Before downgrading it was working on local but not on remote server, and its the same after downgrading.

@evseevnn-zz
Copy link

evseevnn-zz commented Oct 7, 2016

Strange, after downgrading version i try use Model.observe('before save', ...)
and i get context === null inside.

@josieusa @bajtos
P.S. when i use mongo not work before save because by default for mongo version >=3 in connector no findOrCreate method. So, i improve dao.js for fire this event and get this problem. Maybe this depend on use notifyObserversOf? because after use this function i lose context. i tried to use commit of @josieusa but this not helped

@josieusa
Copy link

josieusa commented Jan 4, 2017

@beornharris I reproduced the issue using your authtest repo.
I'll verify my hypothesis that the issue could be caused by the es6-promise dependency of mongodb which is imported here:
https://github.com/mongodb/node-mongodb-native/blob/V2.2.19/package.json#L16
This hypothesis comes from my experience. In fact, in my PR 19 of loopback-context I just made some experiments, and it seems like it could fix problems with other Promise libraries, but only if these are used inside user code, and not some 3rd party library.
Sadly, I just tested that it didn't fix your issue, because that es6-promise is used in a 3rd party module (mongodb), and as I just said, my PR doesn't cover this case. (Also, I don't know yet if this is the root of this issue).
I'm not sure if this can be fixed by user code alone.
I know that you fixed your problem by changing versions, but other people may still be looking for proper solutions.

@Jeff-Lewis
Copy link

@josieusa try telling MongoDB to use cls-bluebird instead and then use cls-hooked instead of cls when initializing cls-bluebird.

In MongoClient.connect we can pass in the promiseLibrary to use. Now I'm not sure if there is an easy way to tell loopback-connector-mongodb to use our instance of cls-bluebird without forking it.

@bajtos
Copy link
Member

bajtos commented Jan 5, 2017

Issue moved to strongloop/loopback-context #21 via ZenHub

@bajtos bajtos closed this as completed Jan 5, 2017
@strongloop strongloop locked and limited conversation to collaborators Jan 5, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

9 participants