Skip to content
Rapcsány Krisztián Rapcsány Krisztián
hu
← All projects iOS and Android app

Event check-in mobile app

The mobile check-in app that staff use at the door to validate tickets. QR scanning, entry, exit, on-site ticket sales and live statistics, on iOS and Android.

React Native Expo TypeScript REST API Biometric authentication OTA updates
The challenge
My role

I designed and built it, from the first version to 2.0.

At the entrance every second counts. If the queue is slow, guests get impatient, and the organiser watches revenue slip away. The door staff need fast, clear feedback: green or red, done.

Before this there was a browser-based scanner. I replaced it with an app that is faster, and where everyone only sees what their job needs.

The solution
01

Camera ticket validation

Scan the QR code with the phone camera and get an instant, colour-coded result: valid, already used, expired or unknown. VIP guests are handled separately.

02

Fast check-in

An optional automatic mode: for a valid ticket the scan alone completes the check-in, with no extra tap.

03

Check-out

A dedicated exit flow, so you always know exactly how many people are inside.

04

On-site ticket sales

A cart and checkout flow, so tickets can also be sold at the door.

05

Live statistics

Arrival chart in 10-minute buckets, sold, checked-in and no-show tickets, a breakdown by ticket type and a chronological list.

06

Roles and users

Five roles (admin, validator, exit staff, gatehouse, viewer). Everyone sees only the screens their job needs. Users are managed from within the app.

Screenshots
Sign in

Staff sign in with their own account, and the sign-in persists.

Choosing the event

Only valid events are listed, so door staff cannot start on the wrong one.

Check-in

The camera waits for a QR code. The event name is shown at the top and can be switched with one tap.

On-site ticket sales

Ticket types at door and member price, with a quantity picker and a running total.

Issuing tickets

A QR code or email for every ticket, with payment and check-in in a single step.

With brand and customer names and personal data removed (except the app store screenshots).

What makes it special

One scan, done

There is a fast mode: for a valid ticket the scan itself admits the guest, with no extra tap.

Five roles

Admin, validator, exit staff, gatehouse and viewer. The gatehouse role, for example, only sees live statistics, and exit staff only see the exit screen.

It measures itself

For every guest it times the scan to the result and to the check-in. It summarises the last fifty on the phone and sends the rest to the server in batches. So I do not just feel that it is fast, I can see it.

Challenges I ran into
01

Weak signal, and nobody gets in twice

On a network error I retry the call once, but only if repeating it cannot do harm. The rule is simple: anything that only reads, or is idempotent on the server, may be retried; anything that is not, I do not call a second time.

02

The first guest is the slowest

On the first scan, setting up the connection eats the time (name lookup, encryption). So the app warms up the connection in the background before the first guest arrives, at most once a minute.

03

The selected event got stuck

In version 1.1.1 I fixed a bug where the selected event stayed in place even when it was no longer selectable. Now the app checks at launch and every time it comes to the foreground, and if the event is no longer valid it sends you back to the event picker.

Under the hood

Tuned for speed

The connection is warmed up before the first guest arrives, and the time from scan to result is measured per guest, so any slowdown shows up quickly.

Works on weak networks

On network errors, repeatable calls retry automatically while non-repeatable ones never do, so nobody can be admitted twice.

Security

The login lives in encrypted storage, protected by biometric authentication for longer sessions. The app keeps verifying that the selected event is still valid.

Operability

Automatic error reporting, fixes delivered in the background without waiting for a store update, and role-based access on the server side too.

Real code

A retry that does no harm

On a weak signal the call is repeated once, but only when that is safe. Non-repeatable write calls deliberately have no automatic retry, so nobody can be admitted twice.

network-retry.ts
/** No response at all = network failure (offline, timeout). A 4xx/5xx reply is not. */
function isNetworkError(error: unknown): boolean {
  return axios.isAxiosError(error) && !error.response;
}

/**
 * Retries a call once on a network failure. ONLY use it for calls that are
 * safe to repeat: reads, or writes that are idempotent on the server.
 */
async function withNetworkRetry<T>(call: () => Promise<T>, retries = 1): Promise<T> {
  try {
    return await call();
  } catch (error) {
    if (retries > 0 && isNetworkError(error)) {
      await new Promise((resolve) => setTimeout(resolve, 700));
      return withNetworkRetry(call, retries - 1);
    }
    throw error;
  }
}
Result

The app is a released, production-grade version (2.0) on both iOS and Android. Admission is down to a single scan, and organisers see arrivals in real time.

Do you need a mobile app or an entry-check solution?

I build mobile apps for iOS and Android, together with their backend.

More projects

Get a quote →