Can "current user" ever be empty?

@Kfawcett, I wanted to say that you are correct. And I was about to write that… And then I decided to test it. (BTW, the documentation you pointed to is not actually helpful around this point. From my reading of it, it’s just a wonky description of what Current User is… and one that I don’t feel particularly helps new users, unfortunately.)

But it turns out that Current User is never empty – even in an API Workflow. This is counter-intuitive… because if we go into the Data tab and create a thing, we find that thing’s Created By is null…

And so, we might assume that, if we run an API Workflow in the superuser context (i.e., we “ignore privacy rules when running workflow”), that this means that Current User will resolve to this null and that this “null User” represents the system/superuser.

Surprisingly, this is not the case.

Let’s explore that in a second. But first: Note that there are quite a few page-level “always available” attributes that we can use to do the “trick” of turning a boolean into a text and thereby get access to the long text input fields that @vini_brito and @anthony and myself will sometimes take advantage of.

Current Date/Time is just one of these. It’s the one that I mentioned in my original explanation to @anthony about how you do this “trick” (which is not a trick or a hack BTW, it’s just what you have to do – it’s completely valid as a technique and doesn’t break any rules or take advantage of some unplugged hole or something, FYI).

I used Current Date/Time in my original example about this as it’s (1) the first one that came to mind and (2) it’s easiest to remember. ALSO, (3) it is a property we can evaluate in both on-page (client-side) and API Workflows (server-side). It’s always available and, logically, it is never empty (and, empirically, this turns out to be true as well).

But there are other on-page properties we could use in on-page workflows. “Current User is not empty” is in fact one of them – it is never empty client-side (and, though it’s surprising, it seems that is never empty server-side) . Let’s consider some other things we can evaluate to do the long text field trick as an alternative:

  1. This url is not empty. This may be superior to Current Date/Time is empty as (1) it’s a text and it turns out that it is significantly faster to evaluate the “emptiness” of a text than it is to evaluate the "emptiness’ of a date [this seems strange, but I mention how I came to discover this here], and (2) when we reference these things, we are in fact asking Bubble to evaluate them and so some function gets run. Getting “this url” is (most likely) just referencing window.location.href. Getting Current Date/Time is probably accomplished by doing new Date(). It’s almost a foregone conclusion that the former is faster than the latter. But, again, this value (“This url”) is not available to us in API Workflow (which makes sense, of course, as we would assume that there is no page/URL context inside of a server-side workflow).

  2. Website home URL is not empty. Website home URL is similar to “This URL” mentioned above. But it’s also available to API Workflows. Interesting, right? In the page, this may be just a reference to window.location.hostname or something similar. In API Workflows it must be something akin to an environment variable (maybe it’s that way in the page too). Anyway, as a text it has all the advantages of “This url” above and it’s accessible in an API Workflow. Also, it is never empty. So this one is a hot pick for sure, but I think there’s actually a better one…

  3. Is Development version formatted as text. “Is Development version” is already a boolean, right? So we don’t need to evaluate if it’s empty, we can just skip right to :formatted as text. Of course it is true in dev mode and false in live mode. But that’s not a big deal. Just put the same text expression in the yes and no long text fields that you get. Illustration:

    This might be the best option. It’s available both in page and in API Workflows. It’s certainly some sort of environment variable. And this probably evaluates the fastest of any other available option. (I have not tested that, but this surmise is reasonable.)

I might have mentioned this to @anthony in my original explanation of how to get to the long text fields, but this would have been harder to explain in the context of that original discussion, right? But now that we’re exploring new dimensions of how to approach this technique, we can all understand what’s going on here.

  1. Honorable mention category: If you only care about doing this trick in the page… Just create a custom state on your page (could be anywhere) of type yes/no. It’ll be false by default. Don’t ever change it. We’re not going to store anything there. We are only going to use it to do this trick. Now that_custom_state formatted as text will reveal the long text fields. In this case, put your text expression in the “no” field, because this expression always evaluates to “no” (it’s like the opposite of Current Date/Time is not empty, ya dig?).

We could go on and on about different candidates and their pros and cons, but the ones listed above are all solid alternatives to Current Date/Time is not empty.

BTW, if you DO need to do this in both on-page and server-side workflows, here’s a screencap of all of the things we have access to in API Workflows:

BEHAVIOR OF “CURRENT USER” IN API WORKFLOWS

OK. So, now that we’ve covered all of that, what about Current User in the context of API Workflows? Let’s get back to that.

The documentation, and our general sense of how Bubble works, leads us to think about API Workflows this way:

When we schedule an API Workflow, that workflow can run in one of two contexts: It can run in the context of Current User, or it can run in the context of the app itself (as superuser, administrator, God-mode, whatever you want to call it).

In the former case, the workflow will respect privacy rules and stuff like that as if it was being run by Current User (Current User in this case means “the user whose action caused this API Workflow to run”, eh? Current User is passed from the client up to the server level.)

In the latter case, the workflow will ignore privacy rules and can do any freaking thing you ask it to. (Even delete the list of “do a search for… all users”.) Neat, right!? And we might kind of assume that this means that the workflow literally runs in some other context (that the workflow is not associated with the Current User that caused it to be scheduled, but is now a “system” workflow). But we’ll explore that.

So when does an API Workflow run in the user context and when does it run in the scary superuser context? Well, we control that with the “ignore privacy rules” checkbox. Simple enough.

Here’s an example. Let’s create two buttons – one will run our API Workflow in the user context (respecting privacy rules) and the other sill run our API Workflow in superuser (ignore privacy rules) context:

The left one has this workflow on click:


^^^ We’re going to run the API Workflow endpoint “do-something”, but respect privacy rules. This is what we’d think of as running “in the Current User context”.

The right one has this workflow on click:


^^^ We’re going to run the API Workflow endpoint “do-something” with no regard for privacy rules. This is what we’d think of as running “in admin/superuser/God-mode context”.

And now you’re wondering, “OK, what’s in our do-something workflow?” It’s real simple: We’re just going to create a logging object that I’ve called an “Inspektor”. This object will record the unique ID of Current User inside the workflow and tell us (somewhat redundantly) if Current User is empty. So the endpoint is set up like this:

And its single action is set up like this:

So, as you can see, that endpoint will respect privacy rules unless we tell it otherwise. Also, it will just create a new Inspektor object that tells us something about what’s going on inside of the workflow.

Now, let’s run it as the Current User. We do that by clicking the left button (I guess I shoulda done this as a video, eh?). Anyway, we expect that what will happen is that (1) Current User will be me and this object will appear as if indeed it was created by me.

I click the left button. And now I go look in the data tab to see what our Inspektor holds:


^^^ Well, we get exactly what we expect. Current User is me (that’s my unique ID), Current User was not empty [duh, we say] and the Created By for the inspector is me (that’s the email for this account representing me).

NOW, what happens if I click the right button? The God-mode button? Will this workflow still have a Current User context? Or will the Current User in this version not be “me”, but that mysterious null User that we think represents the system? Let’s find out!!!

I click the right button (which - remember - runs “do-something” but has the “ignore privacy rules” checkbox checked). Let’s go look in the Data tab at that new Inspektor:

That result might be bit surprising. Apparently, I ran the workflow and I created the Inspektor. Just like in the first case. We might have thought that the Current User would look like system here. But no, User context is preserved. (However, this workflow could have done things that this User could not normally have done, because of privacy rules.)

OK, so can we EVER get Current User to be empty? I can think of one more way this might happen. Let’s make our do-something endpoint totally unprotected, tell it to ignore privacy rules and hit it as an unidentified user.

Here are our changes to do-something:

And now we hit that with Postman:


^^^^ no auth, no body, no nothin’
This should run as the system/app/God-mode… But what does that LOOK like? Let’s examine this new Inspektor:

WHOA! See what happens there? Current User still has a value! But the Inspektor is created with a null value for the Created By user (just as would happen if we created this thing in the Data tab).

The “unique ID” for the “Current User” assigned to this workflow is “non_authenticated_user_myappname_test”, rather than the usual uuid style unique string.

At this point, I know what you’re thinking: What happens if I hit this with authentication? (I tried it and if you’re using a global style app token (the superuser type ones you can create in Settings), this will be something like “authenticated_user_etc…”. If we send authentication with username and pass or an individual user token, we get the unique ID of that User.)

So there you go: ODDLY, Current User is never empty, even in API Workflows. However, the Current User can have a special value in the case we examine above. If Current User is of this special type (an authenticated or non-authenticated “all privileges” type of “user” hitting an endpoint), objects created by the workflow have a null Created By user (indicating they are created by the system).

(I have not tested Recurring Events here, but perhaps I’ll leave that to someone else. There is no reason to think that the behavior will be different.)

6 Likes