Forum Academy Marketplace Showcase Pricing Features

Anyone using Xano as a backend for Bubble?

@JayM

One method could be to create a “follow”:

Follow
Follower user unique ID (text)
Followed user unique ID (text)

or

Follow
Follower (user)
Followed (user)

The first one should be faster because it is lighter since the user object may hold additional fields

I do not claim to have all the answers. This is just a suggestion :+1:t2:

2 Likes

I know it’s different db design methodologies, i just needed it more fleshed out as I wasn’t even sure how it could look like, not how it should look like.

Thanks!

1 Like

I also do not have all the answers, and I think I will have to reach out to Bubble support to get a clear and unambiguous answer on this. From my understanding the relation to an object itself, is no ‘heavier’ than using a text based field storing the unique ID…the reason being as I understand, is that the way the related object field is actually stored as regards to ‘weight’ or data load is just the unique ID anyway.

I think when we are doing a search for something that has a related field to another object, we are not retrieving all of the fields of the related object and thus ‘bloating’ the data load. I think Bubble handles this the same way they do when we have a URL parameter whose value is a unique ID of a data type and when we extract that URL parameter and indicate the type of data it is, we are not searching (this is what they do for slugs basically).

@boston85719

Please do share your findings on the consult with Bubble :+1:t2:

This certainly is pivotal to app building

@petter @lottemint.md @adamhholmes @mikeloc any thoughts on whether Bubble brings-in just the id of a related object … or does it bring all of its fields onto the page?

1 Like

Hey!

I use the Browser’s console network tab for checking such things.

For instance, we have tables Article and ArticleStuff:

Populating some records to these:

Making a repeating group search for the created articles:

So, we can see that the thing type field is returned as a string:


But, if you try to access at least one field of the thing field:

The system makes an extra search:


I hope that’s something you’ve been asking for. :sweat_smile:

5 Likes

Hey Sergei @lottemint.md !

Darn!!!

I appreciate this huge gold nugget response! Brings about the requested guidance and beyond!

So … when we use an object’s field we are actually asking for a subsequent search to be done. Huge!!!

Now I understand why this topic has been interpreted in various ways.

So … one way to “force” for fields not be “searched for” and thus made “lighter” is to limit the ability of the developer to use them. This is when using the unique id as a text comes in. You make a “forced” search when needed! … Not inadvertently perform secondary searches by using fields in constraints or other instances.

If you want you can still use the object to obtain it as a string without loading further fields from it … but you must remember that any time you use it’s fields … you are bringing it in … or “them” in … :sweat_smile:

Many thanks again! :grinning:

4 Likes

Bubble response below

I was able to speak to one of our engineers about this who let me know that we already store the related data type as its unique ID, so making it a text field wouldn’t improve performance.

We only retrieve the nested thing if there are any fields in the nested data type that are being used. So in this example, if there is a text box that says “User’s first name”, we would retrieve the User object only. If it says “User’s House’s address”, then we would retrieve both the User and House object.

It would be interesting to see a performance comparison here. I would imagine having the actual object be related would be faster than having to perform a second search using the text field as unique id constraint.

Thinking about situations when you have a repeating group of Users, in which you do not access any related fields, but when you select a User and send that value to another element (maybe a popup) you do access the fields, it would likely be faster to reference the related field directly than have to perform a search with constraint on the data inside of the popup. It is like when Bubble uses the slug in URL to populate current page content or when you use a Unique ID in a URL parameter and upon retrieval you indicate to Bubble the type of data it is; these usually seem to perform faster than an actual search with constraint of the unique id.

4 Likes

Hi @boston85719 !

Thanks for sharing!

Absolutely. It would be interesting to compare performance.

I agree with the above is it is intuitive for sure. My comment on using the id as text was about “forcing” purposeful searches with all things being equal (meaning … similar performance with both approaches). But this is just a comment, as I am not arguing for its use nor discounting it either.

Sergey @lottemint.md … any further comments on this latest exchange perhaps?

1 Like

As I remember, in both cases, the system makes a request to the DB.
When you fetch data of one thing, it makes the mget request:

The first option is more intuitive (display data), so the best way is to use it.

Also, if you have to display a little list of things in a RepeatingGroup, that’s not an issue at all if you relate to thing’s thing’s field.
You may face an issue, for instance, if you build a feed feature or tasks list one. Not sure why, but the extra searching feature pretty lags (returns items very slowly) when the system asks for 15+ items. We had that issue working on our TMS template. In short, there is RG 1 > RG 2 > RG 3 (list > tasks > subtasks). It worked very slowly. But, I found a way to improve it. I added some conditionals that allowed us to escape the extra searching feature to use the msearch one:

1 Like

You also have access to a regular rest api where you can filter etc. exactly as you do in the editor.
https://manual.bubble.io/core-resources/api/data-api

Regarding you data models I highly suggest looking into data normalization. As others points out, it’s better to keep each model small and simple.

From my reading, this doesn’t solve my problem, I have to pull everything and filter, and then cascade down each sub-type id and make another call and pull that data and filter it separately. What I was looking for is more of a graph QL type of thing, where I can pull an chunk of everything I need which will contain it’s actual data, rather than it’s pointers or unique ids, and do so with one or as few calls as possible.

From a quick search that looks like a big topic. Do you have a specific guide, video or article you like?

Could you describe an example with what data type you want to fetch? There shouldn’t be many scenarios where you need to do serial fetches if the data model is designed.

The rest api works exactly as the frontend “do a search for”. You can have filters etc. so you don’t need to get everything and filter from there, essentially you can make a query that looks like:
SELECT * FROM Posts WHERE User = ‘id’ AND Draft = False.

Obviously just and example and written in sql for comprehension but hope you catch my drift.

Now regarding normalization the basics is:
Define an object by its own properties

A user object for example, should have properties only related to the actual user. Email, name, phone and so on. That is “properties of a user”. What posts a user has liked does not belong in a user - that should go to UserLikes. Otherwise you will quickly get bloated objects as you add features to your app.
So post could be divided up to different sub objects:
Post, PostBoosts etc.
From there it’s easy to fetch PostBoost related to either “current page post” OR “current user”.

1 Like

What I meant was, in what scenario do you need to first fetch one date type, and then fetch another data type based on the first object? It sounds like this is what bringes you the most trouble, and it should be relatively simple to get the correct data with the built in constraints in the rest api.

High level I would do this:
Keep all data in Bubble
Have a backend “login” workflow in Bubble that takes two parameters, email and password. The workflow should return the bubble login token.
In draftbit (if this is the only solution you think will work for you), use the bubble rest api together with the aforementioned token. This will make it so that the api behaves exactly as in the bubble front end when it comes to privacy etc.

I cannot stress enough how much pain you will have trying to keep the databases duplicated, dont do that.

1 Like

I am no longer trying to keep a duplicate of the database, I am moving away from bubble as it is not user-friendly for using external front-ends, at least not enough. It could be, but it wasn’t made to be this way (and the calling it bubble now seems very fitting).

But I still want to challenge your claim about using bubble externally with the same simplicity of using it internally or be proven wrong.

I thought to comment i linked to spells it out but here is a more specific example:

I want to display the feed of posts a user should see when they log in (so all the posts of all the users they follow, like twitter/instagram/etc)). So i have to make a call to get that User and their List of Users they are Following. That is a list of unique user ids.

Now i have to make a call and get each of these users based on their user id. But wait, there is more. Each user has a list of Posts. So now for each user i have a list of unique post ids.

Now i have to make a call to get each of these posts by their id. I am now at hundereds of calls.

I do not see how I can make a call to bubble to pull my logged in user’s data, and within bubble pull everything that cascades from it (all the data of all the posts of all the users this user follows) in a single data json/tree.

Edit: don’t get me wrong, bubble is in many ways absolutely incredible, truly. in what it does there is nothing that comes close to it and every no-code builder has a ton to learn from it. But this holds true up if you only want to use bubble for all your building needs.

Maybe the problem was that Bubble encourages you to design your database with a one to many and many to many relationships, and they even teach you this in their “how to build an app like X” tutorials, because they built their internal natural language interface to work this way. And logically it makes sense for a user to have a lists of posts and a list of users they follow, so i can “only query” that user to get everything related to that user, but little did i know that as far as querying the database, this is not efficient, and i was better off going off against the bubble stream and building and one to one database. It’s only because bubble does behind the scenes magic that this works, but sounds like it also has limits in terms of speed/scalability.

I am now in the process of converting the database i already have to a one to one db but i’m doing it xano to future proof it, and will probably just rebuild the front end on WeWeb.

Bubble is not made to be used by external frontends, that’s why people advise you to stay within bubble :slight_smile:
I have yet to see another no-code database that beats Bubble in terms of flexibility and speed, but would be delighted to hear what better alternatives you have found.

First regarding the user login:
You can make a backend workflow in bubble called “login” with a single action, “log the user in”. It has two parameters, “user” and “pass”

When the user login from you external frontend you can forward the login parameters to the workflow api and it will return a token with a 1 year expiration. It will look like this:

Now this token can make calls ONLY from this user. So the privacy settings in bubble will be enforced, and you don’t need to make extra calls to get the user details etc.

Now to the posts :slight_smile:

What you are describing will almost always require multiple calls. Take a setup where you have tree data types:

Getting posts created by all that the current user follows, can be fetched (with the api), like this:

In the second call I simple insert an array of userId’s collected from the first call, and viola.

Hope that helps

1 Like

I really agree here. One of the most important aspects of building an app is the database layout, and good material is really lacking imho. That’s why I brought up data normalization earlier, because that is the way a database “should” be designed, and if you actually design with that in mind, you will get faster speeds overall because your queries will be simpler and the items will be smaller.

I guess Xano was the answer to my question before. I’m multi database myself btw. because some of my workloads involves millions of records I have a large backend hosted on AWS, but that’s also why I can tell you from experience that it’s a pain to keep duplicates. Avoid that on all cost.
Having a db external and frontend in another place can be great, but I wouldn’t go Xano. The pricing seems steep to me, so if you have somewhat technical skills (which it sounds like), you should consider going all the way and host a db on digital ocean, aws, azure etc.

1 Like

Xano is both faster and more flexible, what it is not, is as abstracted, no-cody, and user friendly as dealing with bubble’s db using bubble.

aws, digital ocean, etc are non-starters. If i wanted to deal with old school databases I wouldn’t be on here and talking about bubble, xano, and draftbit. Xano is not only a very robust no-code backend/database, it is almost the only one. But for better or worse they started from building functionality first, and only now really working on the usability. So i wish i could talk to Xano’s database, in xano, like i can talk to the bubble db in bubble, but that day will come. In the meantime i might have to do more work in xano, but it is a lot more future proofed and I can do a lot more there as a backend than i can do anywhere else as far as i can tell (again, the constraint is that I want to use no-code tools only, or as no-cody as it gets at least).

And yes, xano is expensive, but i am happy to pay never to have to ssh into a server or have to write sql queries.

Thanks for this link, this is very useful.