How to build a Fitness app with Bravo, Xano and RevenueCat

In this tutorial we are going to explain how to build a Fitness app with Bravo Studio, Figma, Xano and RevenueCat. The app will allow users to explore workout videos and food recipes as well as subscribe to premium content.

Some of the features of this app are:


The design

First of all letโ€™s have a look at the design: Bravo Use Case: Fitness app

You can see the design is fully bravorized with containers and Bravo tags, the navigation is set up and the layers that will be bound to real data contain an asterisk (a little trick we do to speed up binding process later). Feel free to explore the design and learn how itโ€™s been built.

For example, check out the Paywall screen. The CTA layer contains the tag [action:purchase:full] which allows the user to trigger the purchase action of the โ€œfullโ€ subscription. Inside it, we have a text layer with [price:full] and {price} within the text, which shows the app user the corresponding price of the subscription.

Letโ€™s duplicate the design and make it of your own.

  1. In Figma, duplicate this design file to your account

  2. In your duplicated file, click Share, then Copy link. Make sure the permission for "Anyone with the link" is can view.

  3. In Bravo Studio, go to Create a new app

  4. Paste the link from step 2 into the input field. Click Connect Bravorized Figma file

  5. Once the app is successfully created you will see the app screens imported from your design.

Make sure your account plan is Olรฉ and you have upgraded to Business app in order to follow the tutorial successfully.

The backend

For the database and API we are using Xano, one of the best no-code tools that you can connect to Bravo and launch a complete backend in minutes.

Bravo users enjoy a 10% discount on any Xano package if you sign up from our referral url ->

One of the coolest features of Xano are snippets. Snippets allow you to clone a complete backend to your own account with just a click, including database entities, data records and API endpoints. We have a complete backend already set up for this tutorial! Awesome, right?

  1. Open this snippet.

  2. Click on โ€œAdd to your Xano accountโ€.

  3. Login and add it to your Xano instance.

  4. From your Workspace, open the Marketplace tab and select the Purchased section.

  5. Once selected, you can review the Snippet and click to install it to your Workspace.

  6. If you have any trouble, check out the full docs on how to add a snippet.

The database consists of six tables:

  • Fitness_workout

  • Fitness_workout_category

  • Fitness_user

  • Fitness_user_recipe

  • Fitness_recipe

  • Fitness_spot

These tables already contain data records for your convenience. For example, Fitness_workout contains the list of workouts with title, description, video url and other fields. This table is connected to Firtness_workout_category by category_id. Feel free to checkout the rest of tables and how they relate to each other.

If you are not familiar with database relationships, you can learn the basics with this tutorial from Xano.

Now letโ€™s take a look to the API endpoints.

  1. Open the API tab from the left menu

  2. Click on Fitness Use Case

You will see a bunch of API endpoints grouped by name. Some of them include custom filters and rules. For example, open /fitness_workout_featured. The endpoint queries all workouts where isFeatured is true and isPremium is false.

Please note that authentication is required for all endpoints (except /auth/signup and /auth/login), which means that the request must include the auth token in the headers for it to run successfully. We'll go over this later, but for now this will give you a sense of the power of Xano ๐Ÿ”ฅ.

Set up custom login with Xano

Now that we have our design connected to our Bravo app and the backend is ready, we can proceed with connecting both by configuring app authentication.

Bravo Studio supports different methods for authenticate users into your app: OAuth 2.0, Firebase login and Custom Authentication. The latter is the method we will use to configure Xano.

Since our Xano Snippet already has the necessary endpoints, weโ€™ll go to Bravo and connect them to our app. If you want to set it up from scratch, learn how to set up Xano as your user authentication backend.

  1. In Bravo, go to API Collections โ†’ Create a new collection

  2. Select Xano Wizard

  3. Go to your account in Xano and copy Your Private Developer API Key

  4. Go back to Bravo and paste the API Key in the input field

  5. Click Continue

  6. Select the instance that contains the cloned snippet and Continue

  7. Select the Fitness Use Case API group and Continue

  8. Now youโ€™ll see the list of endpoints. Click Select all and Continue

๐ŸŽ‰ Congrats! You have imported the API endpoints to Bravo.

Now weโ€™ll need to do some important tweaks to finalise the set up.

  1. Select the request named Auth ยท Login

  2. Select Test Values tab

  3. For email, set as value

  4. For password, set 12345678

  5. Press Send

  6. Go to Selected Data tab and change the Variable Name from โ€œauthtokenโ€ to accessToken

  7. Go to Received Data tab and copy the value of the token (a long string usually starting by โ€œeyโ€)

  8. Click on to the wheel icon nearby the API Collection name

  1. Go to Authentication tab and select Bearer

  2. Paste the copied token in the Token field and click Save

Now all of the requests sent on this screen are authenticated. If in the future the auth token expires, youโ€™ll need to repeat the steps 5 to 10.

Auth tags

Letโ€™s review how the login screen is bravorized. First of all, it has a [page:login] tag in the top-level frame and a [post-login:action] tag that weโ€™ll cover later.

We also have two textfields with form tags: [component:input-email] and [component:input-password]. To submit the form we have a stateful component with two states: default and pressed. The first has the submit action for login forms: [action:login]. Learn more about forms and input fields.

So, now that we have the design ready itโ€™s time to bind it to the backend.


We are going to set up authentication connecting the design elements with the auth API requests that we imported before.

  1. In Bravo Studio, open your app and enter the Data binding screen

  2. On the left panel, select *Email element

  3. Open the Input Destination panel on the right

  4. Select Fitness Use Case โ†’ Auth ยท Login โ†’ email

  5. Repeat with *Password. Select password

Now both variables are bound to the input elements.

Weโ€™ll proceed to set the token returned by the login request to the accessToken variable:

  1. Select the default layer under the CTA frame on the left sidebar

  2. Open the Form response action panel on the right

  3. Select Set Access Token in the On Success dropdown

  4. Type ${accessToken} in the input below it

Youโ€™re all set!

Bravo Vision

Itโ€™s time to test the login! Download Bravo Vision if you donโ€™t have it already.

  1. Open Bravo Vision and login with your Bravo credentials

  2. Open Fitness Use Case app

  3. Continue the intro page

  4. In the login page, enter as email and 12345678 as password

  5. Click the LOGIN button and you should be logged in!

Binding the home page

The home page has three elements bound to API requests:

  • List of categories โ†’ Workout categories ยท List

  • Premium workout card โ†’ Workouts ยท List premium

  • List of workouts โ†’ Workouts ยท List

Letโ€™s connect the visual elements to the data!

List of categories

  1. Select Category slide on the left sidebar

  2. Open the List Item property on the right

  3. Select Fitness Use Case โ†’ Workouts categories ยท List โ†’ data

  4. For *Name (IMAGE), select the same request and the image url param for the Image property

  5. Repeat for *Title, select name for Text

Premium workout card

  1. Select Premium workout card on the left sidebar

  2. Open List Item property on the right

  3. Select Fitness Use Case โ†’ Workouts ยท List premium โ†’ data

  4. Bind *Background image (IMAGE) to video_thumbnail url for Image property

  5. Repeat the binding to match the following:

    1. *Workout short description to description

    2. *Workout title to title

    3. *Workout category to category name

List of workouts

  1. Select Featured workout card on the left sidebar

  2. Open List Item property on the right

  3. Select Fitness Use Case โ†’ Workouts ยท List Featured โ†’ data

  4. Repeat steps 4 and 5 from previous binding (Premium workout card)

Now go to Bravo Vision and refresh the homepage, you will see the elements returned by the database ๐ŸŽ‰

For this tutorial we are not covering the complete binding of the app. Feel free to explore the API requests and continue the process on the rest of the app screens. If you have any question feel free to ask it in the Bravo community.

Youโ€™ll have seen that we bound the premium content, although for the moment every user will see it, and thatโ€™s not what we want to happen. Itโ€™s time to configure In-app purchases!

Set up in-app purchase

To allow app users to purchase subscriptions, Bravo integrates RevenueCat, a platform that provide a subscription backend and wrapper around Apple's StoreKit and Google Play Billing. With RevenueCat you can make sure your users pay for accessing specific pages and content. Instead of having one set up for Android and another for iOS, Bravo connects to RevenueCat to have both platforms available in your app with just one connection.

Our app will be able to do the following:

  • Show Upgrade buttons to free users

  • Show a paywall to unlock paid content, showing the price from the AppStore of GooglePlay (in the userโ€™s currency)

  • Show a list of premium workouts to paid users

App Store Connect configuration

We are not covering the Android/Google Play set up. Check out the full in-app purchase documentation to learn more.

First off we need to create an app in App Store Connect and generate some codes:

  1. Follow step 2 from our iOS publication guide (step 1 is optional) to generate the Certificates, Identifiers and Profiles.

  2. Go to App Store Connect's My Apps page and click on the + button โ†’ New app.

  1. In Platforms select iOS.

  2. Set a Name and Primary Language.

  3. Select the Bundle ID generated previously.

  4. Set an SKU. For example a date: 20230312.

  5. Select Full Access (itโ€™s up to you though) and click Create.

Generate subscription

Your app has been created! Now letโ€™s generate the subscription.

To keep things simple, we are going to create just one subscription for this tutorial. If you want to create more, check out RevenueCatโ€™s documentation.

  1. In the sidebar, select Subscriptions under Features, then click the + button to create a Subscription Group.

  2. Set Fitness premium as Reference Name.

  1. After creating your Subscription Group, click the + symbol to add a new subscription to the group.

  2. Set Full access monthly as Reference Name and fa_699_1m as Product ID.

  3. Click Create.

The product Id is a unique alphanumeric ID that is used for accessing your product in development and syncing with RevenueCat. After you use a Product ID for one product in App Store Connect, it canโ€™t be used again across any of your apps, even if the product is deleted. It helps to be a little organized here from the beginning - we recommend using a consistent naming scheme across all of your product identifiers such as:


Set subscription duration

Once your product is created, you'll be able to set the duration of the auto-renewable subscription. Use the duration dropdown to choose 1 month, and click Save.

Set subscription price

  1. Click Add Subscription Price in the Subscription Prices section.

  2. Select your desired Country or Region and 6,99 as Price

  3. Click Next. Apple will automatically set the price in all App Store regions based off the price and currency you selected. You'll have the option to edit these, but we recommend sticking with the defaults. When done, click Create.

  4. Click Save.

Adding Localization

This is the name and description of the in-app purchase that the user will see.

  1. In the App Store Information section, click the '+' icon next to Localization

  2. Set Full access as Display Name

  3. Set Get access to all videos and recipes as Description

The Subscription Display Name and Description will be visible to the user on the App Store and in their subscription management settings

Reviewer Information

Since we are just testing the set up in Testflight, we will skip this step. Youโ€™ll need it once you want to get your app published.

Subscription Groups

When you configure products for the first time and just set up a subscription group, you may see a warning in App Store Connect:

Before you can submit your in-app purchase for review, you must add at least one localization to your subscription group. Add localizations

Clicking on the Add localizations link will take you to the Subscription Group configuration. Similar to how you added localizations to the product, you'll need to add localizations to the Subscription Group as well.

Don't forget to click Save before exiting.

App-Specific Shared Secret

Generate an App-Specific Shared Secret following this guide.

In-App Purchase Key

Generate an In-App Purchase Key following this guide.

Congratulations! The Apple Store Connect set up is ready ๐ŸŽ‰

RevenueCat configuration

  1. Sign up for a new RevenueCat account here.

  2. Navigate to the RevenueCat dashboard and add a new project from the dropdown in the top navigation menu called Projects.

  3. Set Fitness App Use Case as Project Name.

  4. From Project Settings โ†’ Apps in the left menu of the project dashboard, select App Store.

  1. Set Fitness App Use Case as App Name.

  2. Set your appโ€™s bundle ID (the one in Apple Store Connect) as App Bundle ID.

  3. Set the App-Specific Shared Secret and the In-App Purchase Key generated before.

  4. Click Save.

Products, Entitlements and Offerings

  1. In the Products and pricing menu of the left, click on Products.

  2. Click on + New Product.

  3. Set fa_699_1m as Identifier, **which the Product ID created before in Apple Store Connect.

  4. Click Create Product.

  5. Now go to Entitlements and click on + New.

  1. In Identifier set full.

  2. In Description set Full access to all videos and recipes.

  3. Click Add.

  4. Now click on the full row to open the entitlement just created.

  5. Click on Attach

  1. Click Choose a product and select fa_699_1m - Fitness App Use Case

  2. Click Add.

  3. Go to Offerings and click on + New.

  4. Set default as Identifier. This is critical, Bravo supports only this identifier.

  5. Set any description and click Add.

  6. Now click on the default row to open the offering just created.

  7. Create a + New package.

  8. Select Custom Identifier and set it as full. Set Description as Full access to all videos and recipes.

  9. Click on the table row just created corresponding with the full identifier.

  10. Attach the product fa_699_1m.

RevenueCat set up is done! ๐ŸŽ‰

Review the design tags for In-app Purchase

Letโ€™s open the Figma file and take a look on how itโ€™s been bravorized. For example, the Home page has a container that we want to show only to premium users. We use the [require:purchase:full] tag for that. Note that full is the offering identifier we set in RevenueCat.

Now check out the Paywall page. We are using several tags:

  • [page:paywall] for the main frame, to enable purchase actions.

  • [action:purchase:full] to trigger the purchase action for the full offering we created in RevenueCat.

  • [price:full] and {price} to show the price of the full offering in the userโ€™s currency.

Feel free to explore the design to learn more. For example, Upgrade buttons have the tag [require:purchase:none] to be visible only to free users.

If you want to learn all you can do with Bravo and RevenueCatโ€™s integration, check out the In-app purchase documentation.

Enable RevenueCat in Bravo

The final step is to connect your Bravo app with RevenueCat.

  1. Go to RevenueCat and copy the API Key.

  1. In Bravo Studio, go to your app โ†’ Integrations.

  1. In Payments, enable RevenueCat.

  2. Paste the key in Apple (iOS) API Key.

  3. Click Save.

And we are done! ๐ŸŽ‰


In order to test In-app purchase on iOS, we need to use TestFlight. TestFlight is a platform developed by Apple that allows developers to distribute and test pre-release versions of their apps to a limited group of external testers before releasing them to the general public. It also allows to receive feedback from the group of testers.

Generate the IPA

  1. In Bravo Studio, go to your app โ†’ Publish โ†’ iOS.

  2. Fill the Bundle ID and certificates generated at the beginning of the tutorial.

  3. Click on Get IPA.

In 15-20min you'll receive your IPA ready to be uploaded to Apple Store Connect.

Remember that for each IPA you generate, the Build Number on the Bravo publication form needs to be higher than the previous one.

Upload the app via Transporter

  1. Download the Transporter app here (available on the Mac App Store).

  2. Open Transporter from your computer, enter your Apple credentials and upload the .ipa file

  3. Click Deliver.

It may take some time for the package to appear in App Store Connect (can be minutes or up to an hour). You can check the status in the Activity section on the App Store Connect page.

If you get an alert with the message that some tools are missing and you need Xcode, you will need to install Xcode from the Mac App Store.

Add test users

  1. In App Store Connect click Users and Access at the top.

  2. Click the + button

  3. Fill the New User form. You can add yourself here. Make sure you check the app(s) you want them to have access to.

  4. Click Invite.

The user will need to open the email and click on Accept invitation.

Add testers to Internal Testing

Users added to this group can access the app without needing Apple to do any review process. It's the quickest way to test your app with a bunch of users (up to 10.000).

  1. In App Store Connect, go to Apps and click the app you want to add testers to.

  2. At the top tab menu, click Testflight,

  3. In Internal testing, click the + button.

  4. In the Create New Internal Group modal window, enter a name. For example, "Testers" and click Create.

  5. A new section will appear named as the group created. click the + button right after the title.

  6. In the Add Testers to the Group modal window, select the testers and click Add.

The users will need to click on the View in TestFlight button from the email they received to see the app in TestFlight. Then accept and install the app.

Let us know if you have any questions in the Bravo community!

Last updated