Treasure hunt with QR codes

In this tutorial you will learn to set up and customize an augmented reality scavenger hunt with Onirix, Firebase and Vue. This project can be used to provide a game-like experience to clients and visitors, for example, you could hide QR codes and use them to attract attention to stands at an event, shops at a mall, different points of interest at a festival, etc. You can download the code needed for this tutorial from our GitHub repository.


The standard user experience will be:

  1. Users will find a QR code and proceed to scan it with their phone. This action will open the client application.
  2. If they are not registered, they will need to input their email, a password and some basic information which will be stored. If they are registered but not logged in, they will need to write their credentials.
  3. Once they are registered and logged in, the AR game will start. It consists in capturing some elements like business logos (registered as objective in the code) that will be moving through the screen by clicking on them. The objective for the user is to capture everyone of them (or as much as they can) to increase their score.
  4. After completing a game, they can see their score and a list of every location that they have not visited yet so they know where to go and can continue playing.

Application overview

Screens of the game

The previously described flow is divided in a set of different screens. Apart from the landing page, the user will visit:

Login/Registration page

The login form is a simple view with two fields (email and password) where the user will input their previously defined credentials. The register view is divided in two steps: one for the credentials and one for some basic personal information. Register form register2

How to play

After registering, the user will be greeted with a page containing the instructions to enjoy the experience. How to play

Game screen

When the user starts a game, the user interface will provide him with options to check the booths, read the instructions again and change to full screen mode. It will also track and show their progress in the current game. Scavenger hunt game screen

Game completed screen

When the user completes a game, their total score will be shown. It will also warn the user if they have already completed the current game. Completed screen Already completed screen

Booth list

Finally, the user will have access to the list of all available booths so they can check where all the games are located. The already completed ones will be marked as such. Booth list


Like it was mentioned before, the scavenger hunt is built on three main pillars: Onirix for augmented reality, Firebase for the backend and database and Vue for the web client used to consume the experience and administrate the hunt and its data.

Onirix allows us to create immersive AR scenes that can be directly consumed from our phone browsers (no downloads or installations needed) thanks to its WebAR capabilities. On the Onirix Studio platform we can define different scenes that will be later associated with the booths and customized to fit their logos (or the chosen objective). Furthermore, Onirix, through the Embed SDK package, exposes a series of events that allows us to control, extend and personalize our AR experience using JavaScript.

Google’s Firebase is a platform used to provide database and backend support for mobile and web applications. Its dashboard and easy configuration is ideal to set up quickly the infrastructure needed for the scavenger hunt project. For more information, visit their documentation.

Lastly, Vue is the JavaScript framework used to create the web application where the administrators of the hunt can create the events, add the different booths and link them to scenes defined in Onirix and see the data about users and their played games. It will also provide the user with all the functionalities shown in the previous section. For more information, visit their documentation.


The previously mentioned administration panel built with Vue provides the managers of the event CRUD operation over the event, the booths and user information. To achieve this it invokes the functionalities defined in Firebase.

This panel is divided into the following pages:

Event page

The initial page of the administration panel. If no event is defined, the form will automatically show up so the admin can create it. When an event already exists, its details will be presented and both edit and remove options will be available. Event tab

Booths tab In this page the information about every available booth will be shown on a table. The administrator will be able to add, edit and delete them.

Registered tab

The register tab shows the data of every user that has completed the registration process, even if they have not completed any game.

Played games

Finally, the played games tab shows the data of every completed game so far.

Step 1: Get the code

The first thing you need is to download our template project from the Onirix repositories on Github. Open this link in a new tab, login with your GitHub account and select the Fork option and fill the form. Through the Fork functionality you will be able to make a personal copy of this repository and modify it freely.

After the fork is created, click the Clone button and copy the link inside. Now, open a terminal in the desired folder and execute the “git clone” command followed by the URL you just copied. This will create a local copy of the repository in the folder.

Once it is downloaded, you can open it in your IDE of choice and take a look at the content. However, before you run and test the project, you need to set up Firebase to store the data (events, users, etc) of the scavenger hunt.

Step 2: Set up Firebase

The Ipsum Hunt example uses Firebase to store and consume the data generated in the application and thus you will need to create a Firebase account using your Google account and configure a new project to connect it to the application.

Create Firebase project

Once you are logged in on Firebase’s console, choose the “Add project” option. This will take you to the creation form, input the name for the project, enable (or disable Google Analytics for the project). If you choose to enable it, you will need to create an account on Analytics and Google will automatically create a new property for this project.

Creating Firebase project

If you are interested in setting up Google Analytics on an Onirix Web AR experience check this tutorial.

Finally, select create project, wait for the process to complete and click Continue.

Add and configure the application

In the project overview page, select the </> icon in order to add a web app to the project, fill in the field with the name of the app (in this case “Ipsum Hunt”) and click Register app.

After a short wait, Firebase will provide you with all the information you need to connect to it from the app (apiKey, authDomain, projectId, ...). Once you have copied it, head to the index.ts file under client > src > services > firebase.service.js in your project local repository and paste the values here:

Firebase service code

If you need to view this information again, in the dashboard, click on the project’s name and press the gear icon. This will lead you to the project’s settings where you can check the SDK configuration at the end of the page.

Firestore data in the dashboard

Create the database

Navigate to Firestore Database through the sidebar on the dashboard and select “Create database”. A creation wizard will appear, click next and select the desired location for you Cloud Firestore storage.

Database creation

In this case the example was set up in europe-west, nevertheless you should choose your own region or the one where the project will be used. Click enable and after a short wait your database will be created.

DB created

Once it’s created, you will need to copy the name of the Firebase application (in this case “ipsum-hunt”) and paste it on the .firebaserc file “default” field. You will also have to change Firestore region to the one you selected on two files:

  • On backend > functions > src > index.ts. Backend region
  • On client > src > services > firebase.service.js. Client region


In this example the authentication is handled directly with JWT tokens saved on the Firebase collections. The only requirement to start using this approach is defining a secret for the JWT and generating a token for the Admin user. The defined secret should be written in the CONSTANTS object on index.ts.

After creating it, go to the backend > functions > scripts folder and execute (node) the tokenService.js script setting the _jwtsecret to the one you just defined. Then, copy the generated token printed on the console and paste on client > src > services > firebase.service.js.

FirebaseService admin token

Nevertheless, you can set it up with your authentication method of choice. For example, under the Authentication options on Firebase’s dashboard, Google provides many different types of authentication that can be enabled and configured for your project.

Step 3: Set up mail notifications

When the registered users forget their password and ask for a new one, the application handles it through emails. For this to work a mail service will be needed, in this example Sendgrid is used. However, you can utilize any that you prefer and then change the code accordingly.

To set it up with Sendgrid:

  1. Create a new account and follow their documentation to generate an API key.
  2. Then copy this key and paste it on the CONSTANTS object in index.ts.

You will also need to write the email address that will be used as the sender of the notifications and the URL of the domain where your application will be hosted.

Step 4: Connect to Onirix Studio

The next step is to create an Onirix Studio account and build a new AR project that can be connected to the Ipsum Hunt example. Navigate to , choose the “Register” option on the top right corner and fill both parts of the form and validate the account.

Once you are logged in Studio, you will be presented with several videos, tutorials and some premade assets and projects that you can use to get familiarized with the tool. You can start by creating a new project and building it following some of the other Studio tutorials like:

Create Scavenger Hunt experiences

A Scavenger Hunt consists in capturing certain elements that will appear in the AR experience. Where and when these objects appear is configured through the scene editor of Onirix Studio. So, the first step is creating a new surface scene.

To achieve this, you need to create a new Project and name it. Once it’s created, the form to create a new scene will show up. Select surface type and input a name. Then, click the “Share” button on the top right corner of the page and make sure that the project is set to “Public” as it needs to be public in order to be consumed from the web or the app.

Inside the scene editor, you will now have to add the game objectives that the user will need to capture on their mobile phones. For this to work correctly, the most important step will be to name the elements (one or more) that form your objectives so they can be correctly identified. For example, if your objective is formed by logos, you will have to add elements with the name “logo” to the scene.

Change element names in Studio

To complete the game, the user will have to capture (click) in every objective element that we add to the scene. In order for the client to know which elements are part of the game objectives and how many points does each one give, their names in studio and the number of points must be written in ExperienceVue.js.

const logoNames = ["logo1", "logo2"];
const logoPoints = [10, 20];

You can add more elements with different names to the scene, but they will not be taken into account for the game’s score if they are not in the code.

Set up the token

After you have created a project and the scenes that you want to play on the web application, you need to set your Onirix API key on the client so it can read your Studio data and pull the projects and scenes.

To achieve this, select the project that you have just created, click the Settings button on the top right corner, look for the “Onirix token” section and click “Copy Onirix user token” to copy your key to the clipboard. Finally, paste it on the .env.development and env.production files in the client folder.

Copy Onirix user token Environment variables

Once this is set up, you can start to develop the experience.

Step 5: Run your Scavenger Hunt

After you have cloned the project code, configured Firebase, registered on Onirix account, designed the scenes associated with the hunt and written all the API keys, you can start testing the application and developing it more.

To accomplish this, launch the application on localhost following the next steps:

  1. On one terminal window, navigate to the functions folder inside the backend one. 1.1. Run npm install to get all the npm packages. 1.2. Then, run npm run build:watch so a new bundle is built after every change.
  2. On another terminal, navigate to the backend folder. 2.1. Execute firebase init emulators and select at least Functions, Firestore and Storage. 2.2. On the same terminal, run firebase emulators:start. 4.3. You should be able to see the Firestore Emulator Suite on http://localhost:4000.
  3. On another terminal, navigate to the client folder. 3.1. Execute npm install to get Vue and the other packages. 3.2. Run npm run serve in order to deploy the web client on port 8080.

Apart from third party packages, the client application depends on two Onirix libraries: @onirix/api-client and @onirix/embed-sdk. Make sure everything is correctly installed when running npm install.

Create the event

With everything up and running, navigate to http://localhost:8080/admin to see the administration options of the application.

As there is no created event because you have just started the app, it will automatically ask you to define one. In this example an event just has two properties:

  • Event name.
  • Event logo.

Event creation form

You can cancel the form and keep using the app, however an event is needed in order to actually play the experience.

Add some booths

Once you have created the event, you will have to create some booths where the images that serve as a start point for the AR experience will be defined. To achieve this, navigate to the “Booths” tab, select “New booth” and fill the form. In this example the Booths have the following properties:

  • Booth name.
  • Description.
  • Location.
  • Booth logo.
  • Onirix project: the AR project that will be associated with this booth.
  • Onirix scene: the scene from the project that will be active.

Member creation form

After saving the booth, you will be able to see its information on the table. It will include the URL and the QR code generated to access the booth’s AR experience. All the booths can be edited and deleted from this tab.

Booths tab

When users register on the app, their information will appear in the Registered tab and, when they complete a game, the data of each execution will be present in the Played games tab.

Test the game

Now that you have created an event and some booths with AR experiences linked, you can test them and play the game from the client. First, open a booth’s game link on a new browser window. There you will be greeted with the landing page of the experience.

Client landing page

You can also generate a QR with the IP address marked as public on Vue console and the path of the game URL and scan it from your phone.

As it is the first time that you open the client, there aren’t any users created and thus you will need to click the button and create a new one filling both steps of the form.

Register form 1 Register form 2

After successfully registering, you will be greeted with the tutorial on how to play.

How to play 1 How to play 2

Then the Onirix app will be loaded and you will be able to start playing after scanning the markers. From every window of the application, you will also be able to check all the available booths (the completed ones will be marked as such), your score and the instructions if you need them again.

Welcome view Booths view

Step 6: Deploy your Scavenger Hunt

In order to deploy your own scavenger hunt on a server, you will have to deploy the custom Firebase functions, serve the clients bundle from a server or cloud service and secure the administration panel so only the managers of the application can access it.

Deploy firebase functions

To correctly deploy the firebase functions on index.ts to the online Firebase application, you will need to open a new terminal and run the command firebase deploy. This will compile the code, connect to Google’s cloud services and deploy the functions there.

To achieve this you will need to upgrade your Firebase plan to the “Blaze (pay as you go)” billing plan.

Generate and serve the client’s bundle

After the Firebase backend is deployed, your next action should be to serve the web application so it can be publicly accessed.

To achieve this, first, navigate to the client folder and, from a terminal, run npm run build. This command will compile the Vue application and generate in the “dist” folder all the files that you need to deploy in a server. Although an Apache Server was used for this example, you can deploy this with your tool of choice (AWS, Google Cloud, Window Server, …).

Generated dist folder

Secure the administration panel

As you already saw, this application is divided in two different parts: the administration panel and the client (phone oriented) zone. Through the first one, the manager of the events can create, edit and delete events and booths, and also can inspect the data generated by the users of the AR experience (registered users and the games played by them). On the second part, the user can register if they are a new user, log in with their credentials if they already participated before, read the game instructions, check the available booths and, of course, play with the AR scenes.

As the name indicates, the administration panel should be exclusive to the managers of the application and as such has to be protected from the public. In order to achieve this, in this example Nginx was used but, as mentioned before with the email or the storage, you can implement your preferred method of security.

If you opt for using Nginx for deploying the app, you can protect the admin location from your Nginx configuration file like:

location / {
    try_files $uri /index.html;

location /admin {
    auth_basic "Administrator's Area";
    auth_basic_user_file /etc/nginx/.ipsumhunt.htpasswd;
    try_files $uri /index.html;

For more information on how to achieve this HTTP security with Nginx and how to generate the htpasswd file check their documentation.