# How to use userDir

**URL:** https://discourse.nodered.org/t/how-to-use-userdir/56509
**Category:** Developing Nodes
**Created:** [12 January 2022 09:36 UTC](https://discourse.nodered.org/t/how-to-use-userdir/56509 "2022-01-12T09:36:53Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![borpin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/borpin/32/1765_2.png) [@borpin](https://discourse.nodered.org/u/borpin)
#### Post date: [12 January 2022 09:36 UTC](https://discourse.nodered.org/t/how-to-use-userdir/56509/1 "2022-01-12T09:36:54Z")

</div>

I am going to expose my lack of understanding of the Javascript model here.

I am trying to work on updating the fitbit node. I have discovered that where it is saving the credentials file, is not appropriate for using the node in the HomeAssistant addon (it seems to clean out the folder on each restart when loading the node from the config via git), so I think the right thing is to force it to save the file in the `userDir`, rather than using a hardcoded path (that can then fail).

I believe the way to get to this is to use `RED.settings.get(userDir)`. Is this correct?

However, where I need to call this, I get an error saying effectively `RED` is not available.

As I said, I really do not fully understand the scoping of things in Javascript, so how can I expose this setting at this point in the code such that the file pat include the userDir?

> <https://github.com/borpin/node-red-contrib-fitbit2/blob/d483245600011f90ebf6c6235dc923112e1144db/oauth-helper.js#L4-L4>

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [12 January 2022 10:16 UTC](https://discourse.nodered.org/t/how-to-use-userdir/56509/2 "2022-01-12T10:16:39Z")

</div>

> [@borpin](#):
>
> it is saving the credentials file, is not appropriate for using the node in the HomeAssistant addon (it seems to clean out the folder on each restart when loading the node from the config via git), so I think the right thing is to force i

You shouldn't be reading/writing files in userDir yourself. What exactly are you trying to do here?

---

<div class="post-metadata">

### Author: ![borpin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/borpin/32/1765_2.png) [@borpin](https://discourse.nodered.org/u/borpin)
#### Post date: [12 January 2022 10:17 UTC](https://discourse.nodered.org/t/how-to-use-userdir/56509/3 "2022-01-12T10:17:50Z")

</div>

Save the token credential file.

---

<div class="post-metadata">

### Author: ![hardillb](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hardillb/32/12373_2.png) [@hardillb](https://discourse.nodered.org/u/hardillb)
#### Post date: [12 January 2022 14:38 UTC](https://discourse.nodered.org/t/how-to-use-userdir/56509/4 "2022-01-12T14:38:37Z")

</div>

You should be storing that in the credentials store, not a separate file

---

<div class="post-metadata">

### Author: ![borpin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/borpin/32/1765_2.png) [@borpin](https://discourse.nodered.org/u/borpin)
#### Post date: [12 January 2022 14:41 UTC](https://discourse.nodered.org/t/how-to-use-userdir/56509/5 "2022-01-12T14:41:16Z")

</div>

> [@hardillb](#):
>
> You should be storing that in the credentials store,

Ok, how and where? Any pointers gratefully received.

As I said I have inherited most of this, a lot of this is new to me, but happy to adopt best practices if I possibly can.

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [12 January 2022 14:50 UTC](https://discourse.nodered.org/t/how-to-use-userdir/56509/6 "2022-01-12T14:50:53Z")

</div>

Lets take a step back.

If this is storing Oauth tokens that are generated as a part of configuring the node in the editor, then they should be stored as credential properties on the node so they get stored properly.

If this is storing Oauth tokens that have to be periodically refreshed during runtime, then we don't have a solid solution for this today - there's an old issue on the backlog that covers the details.

The main issue is the storage layer of Node-RED is pluggable. This allows it to run in a cloud environment (for example) that cannot rely on a filesystem to be persistent, so you can plugin a database storage layer under Node-RED. So if a node was to read/write to the file system directly, it won't be a portable node.

There are early plans for a complete overhaul of the Storage API for the 3.0 release in April. This thread has reminded me we should look at providing a more generic get/set capability in that layer for nodes to use in scenarios like this.

---

<div class="post-metadata">

### Author: ![borpin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/borpin/32/1765_2.png) [@borpin](https://discourse.nodered.org/u/borpin)
#### Post date: [12 January 2022 15:55 UTC](https://discourse.nodered.org/t/how-to-use-userdir/56509/7 "2022-01-12T15:55:52Z")

</div>

It is storing Oauth tokens, created initially and refreshed periodically (which seems to work).

> [@knolleary](#):
>
> This allows it to run in a cloud environment (for example) that cannot rely on a filesystem to be persistent.

Precisely my issue. However, it should be reasonable to expect that the userDir is persistent.

If there is no good solution at present, can a solution be suggested such that I can use userDir for now?

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [12 January 2022 15:59 UTC](https://discourse.nodered.org/t/how-to-use-userdir/56509/8 "2022-01-12T15:59:13Z")

</div>

> [@borpin](#):
>
> However, where I need to call this, I get an error saying effectively `RED` is not available.

The line you've linked to is outside of the function exported by the module which gets `RED` passed in.

If you want to use `RED.settings.get('userDir')` then do it inside the exported function. The easiest way to achieve that is to move the `module.exports = function (RED) {` line to the top of the file so everything is inside that function and `RED` is always in scope.

---

<div class="post-metadata">

### Author: ![borpin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/borpin/32/1765_2.png) [@borpin](https://discourse.nodered.org/u/borpin)
#### Post date: [12 January 2022 16:03 UTC](https://discourse.nodered.org/t/how-to-use-userdir/56509/9 "2022-01-12T16:03:13Z")

</div>

Thanks - makes sense. I'll give that a go 🙂

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [12 January 2022 22:06 UTC](https://discourse.nodered.org/t/how-to-use-userdir/56509/10 "2022-01-12T22:06:04Z")

</div>

It should be relatively easy to put the storage code into a function so that you can switch between functions later on - therefore creating your own handler if needed. Of course, that would extend to using a function to wrap whatever Node-RED core ends up with. But if you needed to switch between the file system and, lets say Firebase for Google Cloud or maybe Cloudant for IBM cloud, that should be straight-forward.

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [13 March 2022 22:06 UTC](https://discourse.nodered.org/t/how-to-use-userdir/56509/11 "2022-03-13T22:06:27Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
