[Public Beta] Database change triggers

Hi all,

Thanks all for the positive feedback on this feature. I wanted to address some of the recent replies about how this feature is only available to legacy plans.

For context and history about the current legacy plan situation, I’ll refer you all to this thread started by Josh after the pricing updates from August last year: Pricing updates and thoughts. To reiterate one of his statements:

“we care a LOT about not throwing you under the bus. We completely understand that people are betting their passions on us, and that you are relying on an implicit promise from us to do the right thing to let you continue to be successful.”

We as a company are constantly working to improve the platform in many different ways. One of the ways is with new features that allow more expressivity and power for app creators. Some of these features are rolled out to all plans, including legacy and the Hobby tier - recent features in this category include option sets and the ability to upload large files. We do this when, for example, we feel that a feature is widely applicable to many different kinds of apps, such that any app user, from those just starting off to mature production apps, can benefit.

With other features we choose to place them in a specific paid tier - database change triggers here are an example, as well as the recent Algolia search integration. We feel that features like these give extra oomph to certain users who are generally farther along in their app development process; for example, a person building a prototype on the Hobby tier probably doesn’t yet need the power of Algolia-backed searches. We think hard about the tier that new features are offered in, to see if it makes sense for the value and messaging offered by each tier.

So why did we make a decision to offer new paid features only on the current plans and not legacy? The legacy tiers were created out of a desire to not leave behind anybody who may have bet their project or business on Bubble. If the difference in prices between the legacy and new version of a tier makes a meaningful difference to the economics of your project, we didn’t want to force you to upgrade or be shut out - you can continue on the legacy plan you had before. And after hearing the feedback from the userbase, Bubble decided to give a 2 year period when apps on legacy plans could switch to other legacy tiers - apps on legacy plans will not be left behind, and hopefully by the end of the 2 year period, you’ll know which plan (legacy or otherwise) is suitable for your app’s needs going forward.

Apps on legacy plans are getting the features and improvements that roll out to everybody. However, we feel that since we’re investing in the platform by building new powerful features for users who are further along in their Bubble journey, it is reasonable for us to share in the value that these features bring. If it is important for your app to stay on a legacy plan - please do so. Our hope is to continuously improve the offerings of the current plans such that it’s an obvious decision to switch to a current plan given how much added value the new features provide.

We certainly value our existing users - continuing to empower them and help them grow is a huge part of our daily motivation. As Bubble continues growing and improving, we hope that all our users will continue growing and thriving as well.

6 Likes

Really doesn’t address any of the points raised by your loyal customers who have continued to persevere through inconsistent performance over the years and have been integral in promoting Bubble adoption. The value of loyalty used to be priceless and by rewarding those customers you would have reaped the benefits 10 fold. But ok we get it, and we are all reminded that at the end of the day Bubble owns you, your code, your hosting and we do what is in the best interest of Bubble.

3 Likes

I just read this and we might be missing an opportunity to format the text for better readability. Here’s one attempt to rewrite it:

Trigger Event

This event is defined in the Backend Workflow section and runs workflows triggered by changes in the database.

Whenever an item of the given type is modified, we check the “Only when…” condition of the event, and if the condition passes, we run the workflow.

Use cases

This is useful for situations where a given piece of data could be modified by many different places in your application, and you want to make sure something happens each time the data is modified in a specific way. For instance, you could use this to sync the value of certain data types to an external API whenever the data is modified.

Trigger events are kicked off by any change to the data, regardless if the change is initiated by:

  • a workflow,
  • an API call, or
  • manually editing the data in the editor.

When working with database trigger events, there are two special data types:

  • Thing Before Change”: represents the data of the thing that was changed prior to the changes being made
  • Thing Now”: the current data

where “Thing” will change to match the type of thing you are working with

If a workflow modifies a thing multiple times, we only fire triggers once: “Thing Before Change” will be the data at the beginning of the workflow, and “New Thing” will be the data at the end.

Triggers are also fired when a thing is created or deleted.

If it was created, “Thing Before Change is empty” will be true, and if it was deleted “Thing Now is empty” will be true.

Caveats :warning:

There are several caveats about using data triggers.

  1. Although you can use “Current User” to see which user, if any, initiated the workflow that changed the thing, trigger workflows run with full administrative privileges and privacy roles are not applied while the trigger is running,
    Any searches performed during the workflow will return all results, not just the results the current user is allowed to see.

  2. Triggers cannot kick off other triggers: if data is modified by a workflow initiated by a trigger, we do not check to see if those modifications are eligible for initiating other trigger events.

  3. The “Only when…” condition can only use “Thing Now” and “Thing Before Change” instead of the full list of Bubble data sources. The full list of data sources are available in the actions kicked off by the trigger.

Finally, keep in mind that workflows kicked off by triggers consume capacity, like any other Bubble workflow. If your application kicks off multiple trigger workflows every time data is modified, this can add up to a lot of overhead to the total capacity used by your application. To control this, use strict “Only when…” conditions to make sure you are only running trigger workflows when you need to.

5 Likes

I’m wondering how much this would consume and if I’m going to flood my application?

We pay commissions to our field sales team based on the first paid invoice of the client. So I would have to check:

  1. each incoming invoice. There could be a peak day with 1000’s of invoices paid.
  2. Then I need to check if that’s the first paid invoice of the client.
  3. Check if that client was acquired via a field sales person.

It would probably look like the following:

Trigger on an Invoice
Only when… Invoice's Now Status is "paid"

Action: Make a change to a Sale
Only when… This Sales's Subscription's list of invoices :count is 1

It would be really nice if you could set the trigger on selected fields, instead of all fields…At least for the User entity. I can’t use it there because just the normal use of the app (no data changes) modify some field (hidden?) in the user record and fires the trigger. Or am I missing something obvious?

3 Likes

@rico.trevisan - thanks for the suggestions for our documentation! Tagging @jerementor who is working on our education materials

Regarding your capacity question - there isn’t a great way for me to answer your question quantitatively. Honestly I’d suggest trying it out and watching your capacity charts…

@_Scott - interesting observation. Have you already tried setting a condition on the trigger based on when a particular field changes? Is your observation here implying something about the capacity impact of that approach?

1 Like

yes, you could do it that way, but it would be quite a thrash; for instance on the user thing–it would fire every time the user did something…then that would trigger a storm of “only” evaluations each time. Would use up a lot of CPU trying to catch the needle in the haystack. But it would be really nice if you could just say “look for changes of this (these) fields only.” and it would ignore the rest of the fields. This is important for me because I’m using a pub-sub design pattern. Again, maybe I’m missing something obvious, what do you think?

4 Likes

Our engineering team shared with me that the evaluation of “Only when” conditions is performance-optimized; this optimization should achieve the same as what you’re describing. Please share if you end up trying this!

ooh, interesting. thanks for that!

Hi Bubble, thanks for this great improvement.

I am trying to use this improvement to tidy up the database when things are deleted. However, for some reason when I do a search for related types containing the “ITEM Before change” as an object field, I get an empty array. However, if the do the same change using the “any field contains” the “ITEM Before change” object, then I get the array I am expecting.

For instance, if I delete an “INVOICE” item and, within the change trigger event, I do a search for “LINE ITEMS” whose field INVOICE is the “INVOICE Before change” item, I get an empty array. If I change the search for “LINE ITEMS” with "any field contains “INVOICE Before change UNIQUE ID”, then I get the right array.

I do not thing this should be the expected behaviour.

@allenyang, is this the expected design intent?

Any any case, I think both searches should be able to find the associated arrays.

I’m not sure I fully follow your example. Would you mind filing a bug report with repro steps and more information about your app so that our team can look into it? (In general that’s a faster way to get somebody on the team to look into a potential bug than posting on the forum)

Thanks!

@allenyang

I have a workflow that schedules an API when a user books an appointment. The API is to charge for the appointment at a later time (30 minutes after).

Within that time, I intend to give the client of the appointment the option to include a tip after the appointment is finished. As of now, they have a default tip option but I don’t want to limit or increase the professional user’s earnings depending on the service provided. So therefore I also want the client to have the option to add a one time tip for a specific appointment and not use the default tip.

My issue is that when the workflow runs, it records the data from the appointment at the time it was booked and not when the API is scheduled to run and charge the client. Therefore, it’s not calculating the tip that the client submitted AFTER the appointment was booked. And I don’t want to run a separate workflow to charge the user for the tip because Stripe will take another fee.

Can you tell me if this will work for my use case?

Thanks in advance.

I have created a workflow that is triggered by changes to a specific field of a thing. My application sometimes changes this field in a list of things. When that happens, the background workflow only seems to be triggered by the change to the first thing in the list. See below.

image
image

It sounds like a DB change trigger might be useful as part of a possible solution in your case, but is not going to accomplish what you want by itself. This is more a question of the logic of the workflows you build around this user experience. For example, you could have it so that booking an appointment sets an API to charge for it later, but adding a tip cancels the original scheduled API and schedules a new one.

@SamD - that sounds more like a bug. Could you please file a bug report with the requested info? Our Success team will take a look and escalate to Engineering as appropriate.

I think I did what you are suggesting. I scheduled an API to run the charge later that would give the client time to enter a tip. At the scheduled time for the charge to run, I scheduled two separate API’s; one to run if there was a tip entered, and another to run if there wasn’t a tip entered.

DB trigger change wasn’t working for me.

Hi Josh,

Could you have someone on your team add some spaces in the documentation text :slight_smile:

This event is defined in the Backend Workflow section and runs workflows triggered by changes in the database. Whenever an item of the given type is modified, we check the “Only when…” condition of the event, and if the condition passes, we run the workflow. This is useful for situations where a given piece of data could be modified by many different places in your application, and you want to make sure something happens each time the data is modified in a specific way. For instance, you could use this to sync the value of certain data types to an external API whenever the data is modified. Trigger events are kicked off by any change to the data, regardless if the change is initiated by a workflow, an API call, or from manually editing the data in the editor. When working with database trigger events, there are two special data types: “Thing Before Change” and “Thing Now” (where “Thing” will change to match the type of thing you are working with). “Thing Before Change” represents the data of the thing that was changed prior to the changes being made; “Thing Now” represents the current data. If a workflow modifies a thing multiple times, we only fire triggers once: “Thing Before Change” will be the data at the beginning of the workflow, and “New Thing” will be the data at the end. Triggers are also fired when a thing is created or deleted. If it was created, “Thing Before Change is empty” will be true, and if it was deleted “Thing Now is empty” will be true. There are several caveats about using data triggers. First, although you can use “Current User” to see which user, if any, initiated the workflow that changed the thing, trigger workflows run with full administrative privileges and privacy roles are not applied while the trigger is running, so any searches performed during the workflow will return all results, not just the results the current user is allowed to see. Second, triggers cannot kick off other triggers: if data is modified by a workflow initiated by a trigger, we do not check to see if those modifications are eligible for initiatiating other trigger events. Third, the “Only when…” condition can only use “Thing Now” and “Thing Before Change” instead of the full list of Bubble data sources. The full list of data sources are available in the actions kicked off by the trigger. Finally, keep in mind that workflows kicked off by triggers consume capacity, like any other Bubble workflow. If your application kicks off multiple trigger workflows every time data is modified, this can add up to a lot of overhead to the total capacity used by your application. To control this, use strict “Only when…” conditions to make sure you are only running trigger workflows when you need to.

Hey, @Codeables I flagged this back in March! But no response or change it seems :stuck_out_tongue_winking_eye:,

1 Like

The reference was updated last week :wink:

1 Like

Hi ! Just to say I’m using this feature to generate a SLUG field when creating some new things like USERs or PROJECTs. That’s particularly useful as PROJECTs in my app need to be created at different moments. So I don’t have to add multiple Workflows :slight_smile:

That’s amazing.

Thanks

Michel

Hello,

I think that’s one of the best updates ever!

As a case, that helps to fix duplicate records in our DB without going through all the app.

Thanks so much for this feature!

1 Like