Privacy Policy (GDPR Art 13 + ePrivacy)
Status: appropriate for the current closed-beta scale, revised against an external legal research memo dated 7 August 2026 and then reconciled, the same day, against a line-by-line audit of the shipped source code. Where the two disagreed, the code won: several passages that described an intended design now say plainly what the app does today, and are marked [planned] where the design is still being built. This notice is drafted to satisfy the information obligations of GDPR Article 13 (information to be provided where personal data are collected from the data subject) and the device-access consent rule of Article 5(3) of the ePrivacy Directive 2002/58/EC (as amended by 2009/136/EC), transposed in Denmark as cookiebekendtgørelsen, BEK nr 1148 of 9 December 2011, § 3. It also reflects Apple App Store Guideline 5.1.1(i) and Google Play's User Data / Data safety requirements. These documents are not legal advice and are not a substitute for a professional review — a lawyer review is recommended as the user base and data processing grow, and is advisable before enabling ID/biometric verification.
Last updated: 20 September 2026 — new Sections 3.7a and 3.7b describe the automatic check of your profile and tag photos, and what a report about one photo does: enough different people reporting the same photo hides it while a person decides, temporarily, reversibly, and without anything happening to your account. Section 4 says why that is not an Art 22 decision, and Section 8 gives the retention for the records behind it. Before that, 19 September 2026 — Section 10 now says what account deletion does with your e-mail address on chat rooms and messages (it replaces it), and that copies in our analytics warehouse are deleted within 30 days. Before that, 14 September 2026 — Sections 3.13 and 3.14 now describe advertising on the free plan and Premium subscriptions as they work once each is switched on, with who receives what (Section 6.3), transfers (Section 7), retention (Section 8) and device access for ads (Section 9). Before that, 10 September 2026 — the location lifecycle is now a ladder rather than two cliffs (Section 3.4). Background reading no longer stops dead after 14 days: it narrows instead, so a dormant account is only updated after a large move and only as a coarse area, and stops entirely at 90 days. The automatic expiry in the same section splits the same way — precise position deleted after 14 days of account inactivity (a tightening on the previous 90), coarse presence deleted after 180. Collecting and deleting remain separate mechanisms: one stops us taking new readings, the other removes what was already taken Applies to: the Flybi mobile application ("Flybi", "the app", "we", "us")
1. Who we are (the controller) — GDPR Art 13(1)(a)
Flybi is operated by:
- Controller: Nicholas Gerster Toft Simonsen, operating Flybi as a registered Danish enkeltmandsvirksomhed (sole proprietorship), based in Aarhus, Denmark. As a sole proprietorship, the named individual remains personally the controller.
- CVR number / registered entity: CVR 46574184 — a registered Danish enkeltmandsvirksomhed (sole proprietorship); VAT-registered (MOMS, quarterly returns) since 19 June 2026.
-
Postal address: none is published here. GDPR Art 13(1)(a) requires the identity and the contact details of the controller, not a postal address — the name, CVR number and e-mail address above and below satisfy it, and DSA Arts 11 and 12 likewise require a contact point rather than an address. Write to us by e-mail.
-
Contact e-mail:
support@flybi.app. This is the contact for support and for privacy/data-protection matters. - Privacy policy URL: https://flybi.app/privacy (the canonical URL referenced as
LegalLinks.privacyPolicyUrl; live and published — #646).
EU representative (GDPR Art 27): Not applicable — the controller is established in the EU (Denmark). Art 27 applies only to controllers not established in the Union (Art 3(2)). The Danish establishment is itself the contact point for the supervisory authority and for data subjects.
Data Protection Officer — GDPR Art 13(1)(b)
No Data Protection Officer is appointed; one is not legally required at the
current scale. The controller (Nicholas Gerster Toft Simonsen,
support@flybi.app) is the contact for privacy matters. This position is
re-assessed if scale grows or biometric/ID verification is enabled. We do not
consider a DPO mandatory under GDPR Art 37(1): we are not a public authority,
and our core activity is operating a single consumer app rather than large-scale
monitoring or large-scale special-category processing as our core business in
the Art 37 sense. At the current closed-beta size the "large scale" thresholds in
Art 37(1)(b) and (c) are not met. That will change as we grow: a proximity
service doing background location and processing special-category data crosses
those thresholds well before it feels like a large company, and we re-run the
assessment at each order of magnitude of growth.
Note that a DPO is not required for a Data Protection Impact Assessment to be required — see Section 12.
2. Who Flybi is for — 18+ only (children) — GDPR Art 8
Flybi is an 18-and-over service. You must be at least 18 to create an account. We do not knowingly process the personal data of anyone under 18.
- At registration you must confirm acceptance of our Terms/EULA, and during
onboarding we collect a date of birth to operate an 18+ age gate
(stored as
dateOfBirthon your profile — see Section 3.8). - Under GDPR Art 8 the age at which a child may self-consent to information society services is 16, which Member States may lower to no less than 13. Denmark set this at 13 via the Danish Data Protection Act (Databeskyttelsesloven) § 6(2). Because Flybi is an adults-only (18+) service, that age-of-consent threshold does not in practice apply to our user base — our binding rule is our own 18+ minimum age.
- GDPR Art 6(1)(f) legitimate-interest balancing expressly weighs against processing "in particular where the data subject is a child." Our age gate exists precisely to keep minors off an adults' service.
If we learn that a user is under 18, we will close and erase the account.
3. The data we process, why, and our legal basis — GDPR Art 13(1)(c)–(d)
The table below lists each category of personal data, the purpose, and the
lawful basis under GDPR Art 6 (and, where relevant, the special-category
condition under Art 9(2)). The field names in brackets are the actual
Firestore fields (see lib/core/constants/firestore_fields.dart) and are given
for transparency.
3.1 Account & authentication
- Data: e-mail address; authentication identifiers from your chosen sign-in
provider (e-mail/password, Google, or Apple). (
email) - Purpose: to create and secure your account and let you sign in.
- Lawful basis: Art 6(1)(b) — performance of a contract (you cannot use the service without an account). Where you sign in with Apple, we honour Apple's private-relay e-mail.
- Provision: providing an e-mail/identifier is a contractual requirement (Art 13(2)(e)); without it the service cannot be provided.
3.2 Profile & personality
- Data: display name (
displayName); biography text (bio); profile and tag photos (photoUrl, stored in Firebase Storage); your personality / Big Five self-assessment and its chosen visibility (personality); displayed badges and member number (displayedBadges,signupOrdinal); locale (locale). - Purpose: to present you to other users — in Flybi "the people are the content" — so others can discover and connect with you.
- Lawful basis: Art 6(1)(b) contract for the core profile needed to deliver discovery; Art 6(1)(a) consent for genuinely optional enrichment fields you choose to add (e.g. an optional bio/photo or making your personality profile visible).
- Provision: a minimal profile is a contractual requirement; optional fields are voluntary and may be left blank.
3.3 Interests as "tags", including secret tags
- Data: the interest tags you add to your profile, each marked as an
identity or seeking intent, and optionally flagged secret
(
isSecret); secret tags are only revealed to another user through a mutual reveal handshake (reveal_requests). - Purpose: to find and surface the people who best fit you, and to power the shared-interest discovery experience.
- Lawful basis: Art 6(1)(b) contract (surfacing best-fit people is the core service).
- ⚠️ Special category — Art 9. Free-text tags and "seeking" preferences reveal special-category data under Art 9(1) — sexual orientation and sex life in particular, and potentially health, religious or philosophical beliefs. On a bi/queer-oriented service this is not a borderline case: data that indirectly discloses sexual orientation is special-category data (CJEU C-184/20 OT), and the disclosure does not have to be direct.
- The condition we rely on is Art 9(2)(a) explicit consent, in addition to the Art 6 basis above. We do not rely on Art 9(2)(e) "manifestly made public" for any of it. Publishing a tag on your own profile does not make your other data — your location, your secret tags, who you have connected with — public, and Art 9(2)(e) is read narrowly (CJEU C-446/21 Schrems v Meta). For anything you have flagged secret, Art 9(2)(e) is plainly unavailable: the flag is evidence that you did not make it public.
3.4 Location — proximity discovery, including in the background when the app is closed — see also Section 9 (ePrivacy)
Read this section carefully. It is the most intrusive processing Flybi does.
-
When we read your location. There are two cases. Today they are covered by a single choice: if you turn location on, both happen. We are separating them so you can accept the first and refuse the second, but that is not built yet, and until it is you should read the second case as part of what you are agreeing to. 1. Foreground — when you open a proximity feature (discovery, the optional soulmate scan), the app reads your device GPS at that moment. 2. Background — while the app is closed or otherwise not in use. If you have turned location on at all, Flybi continues to read and send your location when you are not using the app at all, including when it is fully closed. Three separate mechanisms do this: a 500 metre geo-fence around your last known position, which sends a new reading each time you leave it and then re-arms around wherever you now are; the operating system's own background location service (on iOS, Significant Location Change, which reports after roughly 500 metres of movement rather than on a clock; on Android, background location updates); and a refresh each time you bring the app back to the foreground. So readings follow your movement, not a timer. To avoid pointless writes we discard a new reading if you have not moved out of a roughly 5 km cell and your last stored point is under 20 minutes old. 3. We narrow, then stop, if you stop using Flybi. If you have not opened the app for 14 days, background reading does not stop dead — it narrows. From that point we only record a new position if you have moved a long way (roughly 39 km rather than 5 km), we record it only as a coarse area — never the precise position — and we stop refreshing an unchanged one at all, so a phone sitting still writes nothing. After 90 days without opening the app, reading stops entirely — both the geo-fence and the operating system's background service — and nothing is collected while you are away. What we already hold is then kept, as a coarse area only, until the 180-day expiry below.
The narrowing exists because the two obvious options are both wrong. The point of your location is to let people near you find you, and there is nobody to show a precise position to while you are away — but there may well be someone who wants to reach you, and switching off completely used to leave you on the map at a position that quietly stopped being true. Narrowing keeps you findable and roughly right, at a fraction of the reading. This is separate from deleting what we already hold, which happens on its own schedule (see How long we keep things). If you come back, reading resumes the moment you open the app and we do not ask you for permission again — you never withdrew it; we simply stopped doing something there was no longer a reason to do.
-
What is transmitted, and what is stored. What leaves your device is a precise latitude/longitude fix. Where it is stored depends on who can read it:
- Your precise point is kept on a private record only you can read.
- Your profile document — which every signed-in Flybi user can read —
holds only area cells:
geohash4(~39 km),geohash6(~1.2 km) andgeohash7(~153 m). Distances other people see are measured from the centre of your ~153 m cell, not from where you actually are. Every point inside a cell gives the same answer, so the cell cannot be used to work out where in it you were.
So a distance another user sees is accurate to roughly ±75 m. That is the design: precise enough to be useful, never precise enough to be a location.
- ⚠️ What is still being cleaned up — the position today. Until recently the precise point was also written to the profile document, where any signed-in user could read it. That was not the design we wanted and not how discovery is described elsewhere in this notice.
New and updated profiles now publish only the cells described above. Profiles that have not been written since the change may still carry the old precise copy, and that cleanup is being applied in stages — the last stage cannot run until the app update that reads the new cells has reached everyone, because removing the old field from under an older app would empty that person's feed. Until each stage completes, treat a last-known precise position on an un-updated profile as readable by any other signed-in user. [in progress]
Your e-mail address is a separate matter and is still readable on the profile document by any signed-in user. It cannot be moved yet: the chat and blocking features currently find people by e-mail address, and that has to be changed to use an internal ID first. [planned] We will update this bullet when each of these actually lands, rather than quietly dropping it.
- Purpose: proximity discovery only — to show you people within your selected radius, to compute distances, and (where you have enabled it) to keep those distances fresh while you move. Not advertising. Not profiling for third parties. Your location is not sold and not shared with anyone except the processor that stores it for us (Google/Firebase — Section 6.2, EU storage region — Section 7). What other users are shown is a coarse area and a distance. What they can currently read, if they go looking, is more than that — see the bullet above, and the live Hot/Cold game in Section 3.5, which you opt into each time.
- ⚠️ Why this is special-category data, and our Art 9 condition. Flybi is a bi/queer-oriented service. Knowing that a particular person uses Flybi is itself information about their sexual orientation, and a location trail attached to that account is therefore data revealing sexual orientation — special-category data under Art 9(1). A pattern of locations over time can reveal more still (where you sleep, which venues and clinics you visit). We therefore process location on Art 9(2)(a) — your explicit consent, on top of Art 6(1)(a) consent and the separate ePrivacy device-access consent in Section 9. Contract necessity under Art 6(1)(b) and legitimate interests under Art 6(1)(f) are not available for this, and we do not claim them.
- Turning location off turns all of it off, including in the background. Foreground and background are two different things we do with your location, but today they are covered by one choice: the in-app location switch governs both, so there is currently no way to allow one and refuse the other. We are separating them — that is [planned], not built.
What is true today: turning location off in Profile → Location stops both, at the same depth as turning it on, and leaves the rest of Flybi working — you keep your account, your chats and your connections. We will never require location as a condition of using Flybi, and we will never re-ask after you have refused.
-
How often it updates. In the background your position refreshes roughly every 15 minutes once you have moved more than 500 m, and at least every 20–25 minutes even if you stay still. On iPhone this rides iOS's Significant Location Change service (~500 m); on Android it is a balanced-power request at the interval above, never faster than every 5 minutes. A ~500 m self-geofence around your last written position triggers a fresh reading when you leave it. Turning location off in Flybi stops all three. These figures are stated because the app's own consent screens state them, and the two must not drift apart.
-
Retention — one point, no trail. We keep one location point for you: each new reading overwrites the previous one, so your profile holds your latest position and not a history. There is no location-history collection in our database. Your stored point is deleted immediately when you turn location off, when you use "Erase my stored location", and when you delete your account. A two-stage automatic expiry for points nobody has refreshed is running (a single 90-day stage since 18 August 2026, replaced by the two stages below on 10 September 2026). If you stop using Flybi without turning location off:
- After 14 days of account inactivity we delete the precise part of your stored position — the exact coordinates and the ~153 m cell. A coarse area cell remains, so people can still find you, but nobody can be shown a specific distance to you.
- After 180 days of account inactivity the coarse cell goes too, and you stop appearing to anyone. We warn you first: a notification 7 days before, and another 24 hours before.
Opening the app at any point restores a fresh position and resets both clocks; doing nothing lets it go, which is a perfectly good outcome and costs you nothing else — your account and everything in it are untouched.
The periods are measured from your last activity, not from when the point was recorded, so a point you keep refreshing is never removed by this.
Why the split. A stored point stops being treated as precise almost immediately: after 30 minutes of inactivity the app no longer shows anyone a specific distance to you, only a coarse "in your area" reading. So holding the precise version of a dormant point buys nothing anybody can see — which is why stage 1 removes it early, and why that is a tightening on the previous 90 days. What the remaining period keeps is coarse presence, not a live position, and that is the part worth keeping longer: it is what lets someone still reach you after a quiet few months instead of finding you gone. We do not put your coordinates into analytics events, crash reports or server logs; a coarse ~39 km area cell can, however, still appear as a diagnostic key on a crash report, which we are removing.
-
Minimisation (Art 5(1)(c)). Storing a precise coordinate where a coarse cell would do is more than the feature needs. The intended direction is to store only a geohash (or a deliberately rounded coordinate) and compute exact distance transiently.
-
Erasure and withdrawal (Art 7(3) / Art 17(1)(b)): because consent is the only basis here, withdrawing it leaves no basis to keep what was already stored. Profile → Location therefore does both: turning the switch off withdraws consent, stops every location read — foreground and background — and deletes the stored
location/latitude/longitude/geohash4/geohash6fields from your profile and from the owner-onlyprivate/selfrecord they are mirrored into. The same screen also carries a standalone "Erase my stored location" control you can use at any time, including while location is still switched on (in that case the app will store a new point the next time it reads your location). If the deletion cannot be written — you are offline, say — the app tells you so rather than reporting success (#1034). -
Re-confirmation. We re-present this disclosure and ask you to confirm your location consent again at least once every 12 months, and again whenever the frequency, precision, retention, recipients or purpose changes.
-
Provision: location is optional. Declining it disables nearby discovery but you can otherwise use the app; declining background location leaves nearby discovery working whenever the app is open. We will not gate unrelated functionality on granting location.
3.5 Location — live "Hot/Cold" game (real-time precise distance)
- What happens: the Hot/Cold game is a real-time, two-player game that runs only inside an active, mutually-accepted game between you and one other user in your direct chat. While the game is active:
- your device GPS is polled about every 5 seconds on your device to keep the warmer/colder tint responsive;
- the other player's current precise position is read live from their
profile
locationfield (via a real-time listener) and the distance between you is computed on-device (haversine); - the only things posted into the chat as visible messages are distance labels and the colour tint (e.g. "Getting warmer", "🔥 Burning!") — not coordinates;
-
but — and this is the part we want you to know before you accept a game — while the game runs, each player's precise position is written to a live record attached to the chat room. In a private one-to-one chat that record is readable by the two of you. In a group or open room, it is readable by everyone in that room, not only the two players. That record is also not cleared when the game ends, and it is not yet cleaned up on a schedule. Fixing both — restricting the record to the two players, and wiping it when the game stops — is the highest-priority change on our list. Until it ships, do not start a Hot/Cold game in a room with people you would not want to know exactly where you are.
-
the game auto-quits if you drift more than ~5 km apart, and either player can quit at any time.
- Purpose: to play the consensual real-time proximity game.
-
Lawful basis: Art 6(1)(a) consent, and Art 9(2)(a) explicit consent for the special-category dimension described in Section 3.4 — both players must actively invite and accept the game, which is a specific, freely-given, withdrawable consent to share live precise distance for that session. The game is foreground-only: it runs while the chat is open, not in the background.
-
Retention of game data. The live position record described above persists on the chat room after the game ends until it is overwritten by a later game or deleted with your account. It is not ephemeral today, whatever an earlier version of this notice implied.
3.6 Chat messages
- Data: the text and images you send in direct and group chats
(
chat_rooms/*/messages→text,imageUrl,senderEmail,sentAt); room membership and metadata; in-chat system messages. - Purpose: to deliver the messaging feature.
- Lawful basis: Art 6(1)(b) contract for message delivery. Message content is not screened by the disallowed-language filter (Section 5); room names are, like the other public text fields. When a message is reported, the shared chat context is processed for safety under Section 3.7. Message content is not processed on consent, so there is no consent to withdraw for it; you exercise control over it through erasure and account deletion instead (Section 10).
- Note: a message you send is also received by the other participant(s). Their copy may persist in their conversation even after you delete your account (see Sections 6 and 8). The image files you sent are not retained this way: account deletion removes them from Storage, so the delivered message survives without its photo (#1021).
- ⚠️ "Clear chat history" is not deletion. The control in the app is still labelled "Clear chat history" — we are renaming it, because the label promises more than the feature does. What it actually does is record a point in time against your e-mail address on that conversation, and then hide everything before that point from your view only. No message is deleted. The other participants continue to see every message exactly as before, and if you were ever to be shown that conversation again the hidden messages are still in our database. It is best understood as a restriction of processing for you (Art 18), not an erasure (Art 17). If you want data actually deleted, use account deletion (Section 10) or ask us — Section 10 explains what each one really does.
3.7 Safety: reports, blocks & moderation
- Data: user reports you submit or that concern you (
user_reports: reporter/reported identity, reason, free-text details, and a snapshot of the shared chat context); your block lists (blockedUserIds,blockedEmails); and the moderation audit trail (actionTaken,actionedBy,actionedAt,statementOfReasons,slaDeadline). - Purpose: to keep users safe, to action abuse, to meet our content- moderation obligations, and to defend against or bring legal claims.
- Lawful basis: Art 6(1)(f) legitimate interests (the safety of our users and the integrity of the platform — the specific legitimate interest required by Art 13(1)(d)), and Art 6(1)(c) legal obligation where the EU Digital Services Act notice-and-action duties (DSA Art 16–18) apply.
- Reports are handled under our internal notice-and-action procedure: each report is reviewed, an action is taken or declined, and a statement of reasons is recorded against the report. We do not publish a time by which a report is reviewed.
3.7a Automatic check of your profile and tag photos
- Data: your profile photo and the photos on your tags, including the ones
you add while signing up, and the result of checking each one: how likely the
photo is to be sexually explicit or violent, whether it was marked for a
person to review, what that person decided, and when (
image_screenings). If a person removes a photo of yours, a short note saying which of your photos was removed and why, so the app can tell you (photo_notices). - Purpose: to detect offensive and potentially illegal content in these photos, so that a person at Flybi can look at the ones that may break our Terms: sexually explicit material, which our Terms forbid and the app stores do not allow in any app, and photos that may show violence.
- Scope: profile and tag photos only. Photos you send in chat are not checked; in chat, reporting and blocking are the controls (Section 3.7).
- How it works: after you upload a photo, it is checked automatically by Google Cloud Vision SafeSearch, run in our own Google Cloud project through Google's EU processing endpoint, with Google acting as our processor (Section 6.2). The check rates the photo; it does not identify you or anyone in the photo, and it creates no biometric template. The check never blocks or removes a photo for what it shows — see the last bullet below for the one thing that is removed automatically, which is about a link, not about your photo.
- A photo the check marks as likely sexually explicit or likely violent stays up, and a person at Flybi reviews it and decides. Most such photos are fine; only a photo that breaks our Terms is removed.
- If the check cannot run when you upload, it runs again later.
- When a person removes a photo, the app tells you where the photo was: on the "add a photo" screen for your profile photo, or on the tag's card for a tag photo. You see it whatever your notification settings, and by notification too if you allow them.
- Separately, a photo link that does not point at a photo uploaded through Flybi (for example, a link to another website) is removed. This is about where the link points, not about what the photo shows: we can only stand behind photos uploaded through the app. You are told in the same way. The app itself never writes such links.
- Lawful basis: Art 6(1)(f) legitimate interests (keeping our users safe from sexually explicit and violent material, and keeping Flybi available in the app stores, which require this kind of filtering), and Art 6(1)(c) legal obligation where the EU Digital Services Act applies.
- Automated decisions: none about you, and none about what your photo shows. The check only marks photos for a person to review; every decision to remove a photo for what it shows is taken by a person, and the app shows you that person's own reason (Section 4). One thing does happen automatically: a photo link that does not point at a photo uploaded through Flybi is removed, as described above. That is a decision about a link, not about your photo or about you; it affects that one link, and you can upload the photo in the app straight away. If you think a photo was removed wrongly, write to support@flybi.app — the note in the app says so too. A person will look at it.
- Retention: the check result is kept with your account, without the photo, and is erased when you delete your account (Section 8). The note that a photo was removed is deleted when you add a new photo in its place, and with your account.
3.7b Reports about one photo, and a photo hidden while it is looked at
- Data: when you report a single photo, we keep the report itself
(Section 3.7) and, separately, a durable record that you reported that
photo, so the same photo is not counted twice from one person
(
report_subjects, keyed by the photo's owner and which photo it is, with one small document per reporter holding your user ID and when you reported). We also keep a count, per account, of how many of that account's reports a person has dismissed as unfounded (report_reputation). If a photo is hidden, we keep a record of the hide under the photo's owner (photo_hides): which photo, where it is stored, the link it had before, how many people reported it, what the automatic check had said about it, and, once a person decides, the decision, who made it, when, and the reason they gave. - Purpose: to act on reports about one photo without acting on the account behind it, to stop one person hiding a photo they simply dislike, and to be able to put a photo back exactly as it was.
- What actually happens to a reported photo. When enough different people report the same photo, that photo is hidden while a person looks at it. How many is "enough" depends on what the automatic check (Section 3.7a) had already said about the photo, and it is never fewer than two different people. Then:
- It is one photo, and it is temporary. Nothing happens to your account: you keep using Flybi exactly as before, and your other photos stay up.
- A person decides. If they decide the photo is fine, it goes back, and the same people cannot hide it again by reporting it once more. If they decide it breaks our Terms, it is removed and you are told which rule it broke, in their own words, in the app.
- The photo itself is never deleted while it is hidden, and putting it back is a matter of publishing it again.
- The link to the photo changes. Hiding works by making the old link stop working, so any copy of that link — for example one you had saved — stops resolving, and a restored photo has a new link. Inside the app you will not notice.
- We do not say how long the looking takes. We will not promise a speed we cannot keep. What we do promise is that a person decides, and that the photo is hidden rather than deleted until they do.
- You are not told who reported you, and the person you report is not told it was you.
- Lawful basis: Art 6(1)(f) legitimate interests (protecting our users from sexually explicit and violent material, and acting on reports at all as one person), and Art 6(1)(c) legal obligation where the EU Digital Services Act notice-and-action duties apply.
- Automated decisions: the hide is automatic — it is the one moderation measure at Flybi, other than the link rule in Section 3.7a, that takes effect before a person has looked. It is deliberately narrow: it concerns one photo, it is reversible, it changes nothing about your account or your ability to use Flybi, and it exists only so that a photo several people say is sexually explicit is not on display while it waits. It is not a decision with legal or similarly significant effects on you within the meaning of Art 22 (Section 4). The removal of a photo is always a person's decision. If you think a photo was hidden or removed wrongly, write to support@flybi.app.
- Retention: the per-reporter records and the dismissal counts are kept with the reports they come from, under the same limit and the same reasons as the reports themselves (Section 8). The hide record lives under the photo's owner and is erased when that account is deleted.
3.8 Date of birth / 18+ age gate
- Data: your self-declared date of birth (
dateOfBirth). - Purpose: to operate the 18+ age gate and keep minors off an adults' service.
-
How it is checked, plainly: the date you type during onboarding is checked in the app, on your device. We do not verify it against any document, and we do not use any age-estimation or ID service. It is a declaration we take at face value, backed by the reporting and moderation process in Section 5 — not a proof of age. [planned] a server-side check as well.
-
Lawful basis: Art 6(1)(c) legal obligation and/or Art 6(1)(f) legitimate interests (age assurance / child protection).
- Minimisation note (Art 5(1)(c)): we store the full date of birth. [LEGAL REVIEW: consider storing only a verified "over-18" flag plus the verified date rather than the full DOB where the feature allows, to minimise the data held.]
3.9 Push notifications & device tokens
- Data: Firebase Cloud Messaging (FCM) device tokens (
fcmTokens) and your notification preferences (notificationPreferences). - Purpose: to send the in-app notifications you have enabled (chat messages, requests, game invites, strong-fit alerts, etc.).
- Lawful basis: Art 6(1)(b) contract — delivering the notifications you have asked for is part of the service. You control which ones you get in the app; the operating-system notification permission is a separate technical control over whether your device displays them at all.
- Retention: a device token is deleted when you turn that device's notifications off, when the token is refused by the messaging service as stale, and when you delete your account.
3.10 Technical, security & abuse-prevention data
- Data: rate-limit markers (
rate_limits), App Check attestation signals, and server-side logs (which may include technical identifiers such as IP address). - Purpose: to operate and secure the service and to prevent abuse.
- Lawful basis: Art 6(1)(f) legitimate interests (security, fraud and abuse prevention, service reliability). This covers server-side records only. Anything that writes to or reads an identifier from your device — crash reporting, performance monitoring, analytics — is dealt with separately in Section 3.11, which also explains that those three are currently running without the consent step they need, and what we are doing about it.
App Check. Firebase App Check is integrated, but its enforcement is currently switched off on our server functions, including account deletion — the device-attestation providers it depends on are not yet registered with Apple and Google. So while it is listed here and in Section 6.2 as something we use, it is not protecting those paths today. Section 13 says the same.
3.11 Crash diagnostics, performance monitoring and analytics
⚠️ Read this first — what happens today, 7 August 2026
The consent design described in the rest of this section is not yet built. In the app as it ships right now:
- crash reporting, performance monitoring and usage analytics all start automatically when you open Flybi — before you are asked anything, and whether or not you would have agreed;
- usage analytics records an "app opened" event at launch, ahead of any consent screen;
- there is no in-app switch that turns any of them off. The two switches described below do not exist yet;
- your Flybi user ID is attached to crash reports as the identifier for that device, and it is not cleared when you sign out — so on a shared device, later crashes can still carry the previous account's ID;
- a fault in one chat feature can additionally attach your e-mail address to a crash report, and a coarse (~39 km) area cell can be attached too.
We are not describing that as a design. It is a defect, it is the top of our engineering list, and until it is fixed the legal bases set out below are not being properly obtained. Everything marked [planned] below is where we are going, not what the app does now. If you want us to delete diagnostics data already collected about you, e-mail us (Section 1) — note that account deletion does not currently reach these systems (Section 10).
[planned] These will be off by default, with nothing running unless you switch it on, and the app working identically either way.
- The services: Firebase Crashlytics (crash reporting), Firebase Performance Monitoring (app and network performance), and Google Analytics for Firebase (usage analytics).
- Data — Crashlytics: a crash-dedup UUID, the Crashlytics Installation UUID, the Firebase Installation ID, a Firebase session ID, crash timestamp, bundle ID and app version, OS name and version, jailbreak/root status, device model, CPU architecture, RAM and disk, instruction pointers, method and function names, exception classes and messages, fatal signal names and codes, binary image names/UUIDs/sizes/base addresses, app foreground or background state, screen rotation, proximity-sensor trigger status, and version-control information.
- Data — Performance Monitoring: the Firebase Installation ID, device model, OS, orientation, RAM and disk, CPU usage, mobile carrier (MCC/MNC), radio and network type, country derived from your IP address, locale, app state, network URLs (without query parameters), response codes, payload sizes and response times, and IP addresses. Unlike crash reporting this collects from every session, not only when something fails.
-
What of your identity currently reaches these reports. Your Flybi user ID is set as the identifier on crash reports and stays set after you sign out; your e-mail address can be attached when one particular chat operation fails; a coarse ~39 km area cell and a chat-room ID can be attached the same way; and every log line the app records at "info" level or above is sent along as a breadcrumb. Your precise coordinates, name, bio, tags and connections are not — those are actively stripped. [planned] none of it should be there: the intended position is that no Flybi identifier or profile field is passed into a crash report at all, which is what the rewrite of this pipeline (to an explicit allow-list) is for.
-
Lawful basis: Art 6(1)(a) consent, and — logically first — your consent under Art 5(3) ePrivacy / cookiebekendtgørelsen § 3 to write and read a persistent installation identifier on your device. There is no legitimate-interest route for that device access, and none of the ePrivacy exemptions covers crash reporting, performance monitoring or analytics: the test is what is strictly necessary from your point of view, and Flybi works the same whether or not a crash report is ever sent. We therefore do not rely on Art 6(1)(f) for any of this. As the box at the top of this section says, that consent is not currently being asked for, so the collection happening today does not have the basis it needs. We would rather say that than dress it up.
-
Separate controls. [planned] "Crash & performance diagnostics" and "Usage analytics" will be two independent switches, both off by default, both refusable without any loss of functionality, and both re-accessible at any time in Settings. Neither switch is in the app today.
-
Withdrawal. [planned] When the switches ship, turning either off will stop collection, call
deleteUnsentReports()so anything queued on your device is discarded, and delete the Firebase installation where that is technically possible. Google documents that opting out "will apply the next time the user launches the app", so we will also hold our own local flag that our code honours immediately. Today there is no in-app way to switch this off. If you want it stopped, or want diagnostics data already collected about you deleted, e-mail us (Section 1) and we will do it by hand. -
Retention. Google retains Crashlytics data for 90 days; Performance Monitoring data for 30 days where it is associated with an IP address and 60 days where it is associated with an installation. These periods are enforced by Google, not by us.
-
Recipient and role: Google LLC acts as our processor for Crashlytics, Performance Monitoring and the Analytics measurement service, under the Firebase Data Processing and Security Terms. We keep Firebase Service Data sharing and the Analytics data-sharing settings off, so Google's controller-to-controller measurement terms — under which Google would be an independent controller of shared data — do not engage.
-
Transfers: this data goes to Google LLC in the United States. The transfer relies on the EU–US Data Privacy Framework, under which Google LLC is certified, with the EU Standard Contractual Clauses in Google's terms as the fallback safeguard. See Section 7.
- If you say no, we are not blind. Apple collects crash logs from TestFlight testers under Apple's own terms and shares them with us, and Google Play's Android vitals reports crashes from users who opted in to sharing diagnostics at the OS level. Neither of those requires anything from us on your device, and neither depends on your answer here.
3.12 Best-fit / ML signals
- Data: server-computed best-fit embedding vector (
embeddingVector), connection-outcome rows used to improve who we surface (connection_outcomes), encounter records and streak stats (flybi_encounters,flybi_user_stats). - Purpose: to compute and improve who we surface to you.
- Lawful basis: Art 6(1)(b) contract (surfacing best-fit people) and Art 6(1)(f) legitimate interests (improving how well we surface people).
3.13 Advertising (free plan)
Flybi pays for itself partly with a small number of ads shown to people on the free plan. Advertising is controlled by a switch on our side and may be off; while it is off, nothing in this section happens. Premium subscribers never see ads (Section 3.14).
- Where ads appear: as a card in the discovery feed and as a row in the chat list, each marked "Ad" ("Annonce" in Danish) and laid out differently from profiles and venues. Never inside a conversation, on a profile, or full-screen.
- Who serves them: Google AdMob. Google chooses and delivers the ad, counts that it was shown or tapped, and detects fraud. For that, Google acts as an independent controller under its own terms, not as our processor (Section 6.3).
- What the ad software processes on your device: the device's advertising identifier (on Android the advertising ID; on iOS the IDFA only if you allow tracking), app and device information such as model, operating-system version and language, your IP address, from which Google derives an approximate location (roughly the city), and which ads you saw or tapped. It also stores your consent choice on the device.
- What we do not give it: we do not pass your profile, tags, precise location, chat, age or any identifier of your Flybi account to the ad software. Flybi's own location readings (Sections 3.4 and 3.5) are never used for advertising; the approximate location above is Google's own derivation from the network connection.
- Personalised or not, your choice. In the EEA and the UK, Google's consent message asks you before the first ad is requested. Personalised ads, based on a profile Google or its advertising partners hold about you, run only with your consent (Art 6(1)(a)) and, on iOS, only if you also allow tracking in Apple's App Tracking Transparency prompt. If you decline, ads are not personalised; Google still uses the data above to deliver and count the ad, limit how often you see it and detect fraud, as controller on its own legal basis. Declining does not remove ads and changes nothing else in Flybi.
- What Flybi itself records: that an ad slot was shown or tapped, with the name of the placement only, in our usage analytics (Section 3.11). No ad content, advertiser or identifier.
- Change your mind at any time: Profile → Privacy & Ads → Manage ad consent reopens the choices. On iOS you can also change tracking in Settings → Privacy & Security → Tracking.
- More about Google's use: https://policies.google.com/technologies/partner-sites
3.14 Premium subscriptions and payments
- How you pay: Premium is an optional, auto-renewing subscription bought through the App Store or Google Play. Apple or Google takes the payment and handles renewals, cancellations and refunds, as an independent controller for your payment and billing data under its own terms (Section 6.3). Flybi never sees your card or bank details.
- What we keep: a purchase record linked to your account, holding the store, the plan (1, 3 or 12 months), the store's own reference for the subscription (a Google Play purchase token or Apple's original transaction ID), its expiry date, whether it was refunded or revoked, and when the record was created and updated. Your profile shows that you have Premium, until when, and that it came from a purchase.
- Linking the purchase to your account: when you buy, the app gives the store a token derived one-way from your Flybi account ID, so the purchase cannot be claimed by a different account. It does not reveal your account ID.
- Checking the purchase: the app sends the store's proof of purchase to our server once. For Google Play, our server confirms it with Google's Play Developer API; for the App Store, it checks Apple's cryptographic signature on the transaction. The proof itself is not stored. Afterwards Apple and Google notify our server when a subscription renews, lapses or is refunded, and for Google Play we also re-check subscriptions periodically.
- Purpose and legal basis: providing the subscription you bought, Art 6(1)(b) contract; confirming that a purchase is genuine and belongs to your account, Art 6(1)(f) legitimate interest in preventing fraud.
- Retention: kept while your account exists and deleted with it (Section 8). Apple and Google keep their own billing records under their terms and the law that applies to them.
4. No automated decisions with legal effect — GDPR Art 13(2)(f) / Art 22
Flybi uses automated processing to rank and surface profiles (best-fit and soulmate/strong-fit scans) and an automated text filter to screen display names, bios, tag titles, tag descriptions and room names for disallowed language. These help us run the service and keep it safe.
We do not make decisions producing legal effects concerning you or similarly significantly affecting you solely by automated means within the meaning of Art 22(1). Moderation actions that restrict an account or content (warn / hide / suspend) are taken by a human moderator, who issues a statement of reasons (DSA Art 17).
The automatic photo check (Section 3.7a) takes no decision about you and none about what your photo shows: it only marks photos for a person to review, and a person decides whether a photo is removed. The one removal made without a person is of a photo link that does not point at a photo uploaded through Flybi, a technical rule about where a link points rather than a judgement of the photo or of you. It concerns one link, you can add a photo through the app straight away, and nothing else about your account changes. You can still ask a person to look at it (Section 3.7a).
One further measure takes effect before a person has looked: when enough different people report the same photo, that photo is hidden while a person decides (Section 3.7b). We treat this as falling outside Art 22(1) and we say why, rather than asserting it: it concerns one photo, it is temporary and reversible, it is not a decision about you — your account, your other photos and everything you can do on Flybi are untouched — and the decision that actually removes a photo is taken by a person, who gives their reason. The photo is not deleted while it is hidden. Even so, we tell you it happened and why, and support@flybi.app reaches a person who can put it back.
5. How we keep the service safe
We operate: an in-app report flow and block capability; a human moderation process with statements of reasons and warn / hide / cooldown / ban actions; a disallowed-language filter on display names, bios, tag titles, tag descriptions and room names (chat messages are not filtered; there, reports and blocks are the controls); an 18+ age gate; and Terms/EULA acceptance at registration. These underpin the safety processing described in Sections 3.6–3.8.
Your profile and tag photos are also checked automatically after upload. A photo the check marks is reviewed by a person, who decides; nothing is removed automatically for what it shows (Section 3.7a). Photos sent in chat are not checked; there, reports and blocks are the controls.
You can also report a single photo, from the photo itself. Reports about one photo act on that photo: when enough different people report the same one, it is hidden while a person decides, and nothing about the reported account changes (Section 3.7b).
6. Who receives your data — GDPR Art 13(1)(e)
6.1 Other users
By design, your profile (name, photo, bio, public tags, approximate area, badges and — if you make it visible — your personality profile) is shown to other signed-in users so they can discover and connect with you. Chat content is shared with the people in that conversation. Secret tags are shared only via a mutual reveal.
More than that is currently readable, and you should know it. Your profile record as stored today also carries your e-mail address and your precise last-known coordinates, and it is readable by any signed-in Flybi user, not only by the people we choose to show you to. Nothing in the app displays those fields — but "not displayed" is not the same as "not shared", and we are not going to describe it as if it were. Removing them from the readable copy is [planned]; see Section 3.4.
Open rooms. If you create or join an open ("Stop Bi") room, that room is listed to other signed-in users so they can find and join it. The listing shows its title and image, its join tags, and its approximate area — a geohash cell of roughly 1.2 km × 0.6 km, the same coarse grid used for profile discovery. Your precise coordinates are not in the room record: it holds only the cell, so the point you were standing on when you opened the room is not recoverable from it (#1033). Rooms you keep private are visible only to their participants and to anyone you invite.
⚠️ What an open-room listing actually carries. Everything in the room's record travels to the device of every signed-in user who lists open rooms — not just the parts the app puts on screen. That includes the e-mail addresses of the room's participants, of anyone invited to it, and of whoever created it (room membership is keyed by e-mail throughout Flybi), and the text of the last message sent in the room. The app does not display the last message or the addresses in the discovery card, but they are delivered all the same, and a determined person can read them. If you would not want your e-mail address known to strangers, do not join open rooms until we have fixed this. Re-keying membership from e-mail to an opaque ID is tracked as #696 / #600.
What a new joiner can see. When someone joins an open room, they are shown messages sent before they arrived — currently up to the most recent 200 messages of that conversation. There is no server-side limit behind that number: it is a cap the app applies, and one we can change remotely, so it is a product setting rather than a guarantee. People who were not present when you wrote something can therefore read it. A real cap — post-join only, or a short window — is [planned].
6.2 Processors (sub-processors) acting on our instructions
We use Google Firebase as our backend processor (the contracting Google entity — e.g. Google Ireland Limited and/or Google LLC, as applicable under Google's Cloud/Firebase terms). The specific services are:
- Cloud Firestore — profile, tags, chat, reports and related documents;
- Firebase Authentication — sign-in (email/Google/Apple);
- Firebase Storage — profile and tag images;
- Cloud Functions (region europe-west1, Belgium) — server-side logic including the account-erasure cascade and moderation triggers;
- Cloud Vision API (SafeSearch) — the automatic check of your profile and tag photos (Section 3.7a), through Google's EU processing endpoint. It reads the photo where it is already stored and returns only a rating;
- Firebase Cloud Messaging (FCM) — push notifications;
- Firebase Remote Config — configuration;
- Firebase App Check — anti-abuse attestation. Integrated, but its enforcement is currently switched off on our server functions, including account deletion and chat-history clearing (Section 3.10). Treat it as present but not yet doing its job.
- Google BigQuery — some Firestore collections, and our crash and usage analytics, are exported to a Google BigQuery dataset for product and cost analysis. Copies there that belong to a deleted account are deleted within 30 days (Section 10).
And, for crash, performance and usage data (Section 3.11) — which, as that section explains, are currently running by default rather than on your switch:
- Firebase Crashlytics — crash reports;
- Firebase Performance Monitoring — app and network performance data;
- Google Analytics for Firebase — usage analytics.
Google processes this data on our behalf as a processor under the Google Cloud / Firebase Data Processing and Security Terms (an Art 28 Data Processing Agreement is in place via acceptance of Google's DPA). For the three diagnostic and analytics services above, the contracting entity is Google LLC and the data reaches the United States — see Section 7. We keep Google's data-sharing settings off so that Google does not become an independent controller of that data. No other processors (for example a third-party e-mail provider) are shipped in the current build; this list will be updated if any are added. (Current position; to be confirmed in a professional review as the project grows.)
6.3 Independent controllers: Google for ads, Apple and Google for payments
These companies decide for themselves how they use the data they receive, under their own terms and privacy policies, so they are not our processors:
- Google (AdMob), for ads on the free plan when advertising is switched on (Section 3.13), under the Google Ads Controller-Controller Data Protection Terms and https://policies.google.com/privacy.
- Apple (App Store) and Google (Google Play), for Premium payments (Section 3.14), under https://www.apple.com/legal/privacy/ and https://policies.google.com/privacy.
6.4 Authorities and legal claims
We may disclose data to public authorities (e.g. Danish Police) where required by law or to address a serious risk to life or safety, and to our advisers to establish, exercise or defend legal claims.
7. International transfers — GDPR Art 13(1)(f) / Arts 44–49
Our processing is configured for the EU/EEA: Cloud Functions run in
europe-west1 (Belgium) and Firestore/Storage are provisioned in an EU
region (e.g. eur3 / europe-west1). (Current configuration; to be confirmed
in a professional review as the project grows.)
Three things nonetheless leave the EEA:
- Crash diagnostics, performance monitoring and analytics (Section 3.11) are processed by Google LLC in the United States. Note that these are currently running for everyone rather than only for people who switched them on — see the box at the top of Section 3.11.
- Some Google support, security or operational functions for the EU-hosted services may involve access from outside the EEA.
- Advertising and payments (Sections 3.13 and 3.14): Google LLC and Apple Inc. process that data in the United States as independent controllers, under their own transfer safeguards. Both participate in the EU–US Data Privacy Framework.
For the first two, the mechanism is the same. Google LLC is certified under the EU–US Data Privacy Framework, which the European Commission has found to provide an adequate level of protection (Art 45), and the EU Standard Contractual Clauses are incorporated into Google's Data Processing Terms as an Art 46 safeguard that stands behind it. We keep the SCCs in the contract chain deliberately, so that the transfer remains covered if the Framework is ever suspended or annulled — a legal challenge to it is pending before the Court of Justice. You can request a copy of the relevant safeguard using the contact details in Section 1.
8. How long we keep your data (retention) — GDPR Art 13(2)(a)
We keep personal data only as long as needed for the purposes above. Every period below is anchored to an event we actually record — the date you deleted your account, the timestamp of the last message in a conversation, the date a report was closed — so that you can work out the period that applies to your data rather than reading a general promise.
⚠️ How these periods are enforced today, 7 August 2026. Deletion you ask for — account deletion, erasing your location — runs immediately, as a real server-side job, and you can rely on it. The time-based periods in the table below are a different matter: the scheduled clean-up job that is meant to enforce them has not been built yet. Rows marked [not yet automatic] describe the limits we hold ourselves to and will delete to on request, not a sweep that runs on its own. We are telling you this instead of quietly loosening the wording, and building the job is the fix.
| Data | Retention |
|---|---|
| Account, profile, tags, photos, personality, stats | Kept while your account exists. Erased when you delete your account (Section 10) — see the erasure timing note below. |
| Location (Section 3.4) | One point only. Each reading overwrites the previous one, so no trail is built. The stored point is deleted when you turn location off, when you use "Erase my stored location", and when you delete your account. In addition, an un-refreshed point expires automatically in two stages: the precise position after 14 days of account inactivity, and the remaining coarse area cell after 180 days, with notifications 7 days and 24 hours before the second. Running since 18 August 2026; two-stage since 10 September 2026. |
| Live Hot/Cold game session data | The live position record written during a game stays on the chat room after the game ends until a later game overwrites it or your account is deleted (Section 3.5). Clearing it when the game stops, and sweeping old records, are [planned]. |
| Chat messages | Kept for the life of the conversation. The 12 months after the last message limit is [not yet automatic] — no job currently deletes dormant conversations. On account deletion your profile is erased, but messages you sent stay in the conversations they were delivered to, on our legitimate interest in the other participants' own record of their conversation (Art 6(1)(f)); you can object to that under Art 21 and we will weigh it. The images you sent are an exception: they are deleted from Storage by the erasure cascade, so a retained message shows the text but no longer the photo (#1021). |
| User reports / safety & moderation records | Our limit is 24 months from the date the report is closed (actionedAt), and these are kept beyond your account deletion, because they are needed to keep other users safe and to establish, exercise or defend legal claims (Art 17(3)(e), and our legitimate interest under Art 6(1)(f) in the safety of the people who reported). [not yet automatic] — deletion at 24 months is done on request or by hand until the scheduled job ships. Reports that led to a ban, or that concern serious harm, may be kept longer where a specific matter is live — we will tell you the period if you ask. |
| Photo check results (Section 3.7a) | The result of each check (the ratings, whether the photo was marked for review and what the reviewer decided, never the photo) is kept while your account exists and erased when you delete your account. A photo waiting for another check is listed in a queue until it has been checked, and that entry is erased with the account too. The note that a photo was removed is kept until a new photo replaces it, and is erased with the account. |
| Report-counting records and reporter reputation (Section 3.7b) | The record that you reported a particular photo, and the count of how many of your reports were dismissed, belong to the reports they were derived from and are kept under the same limit — 24 months from the date the report is closed — and for the same reasons. Like the reports, deletion at 24 months is [not yet automatic], and these records can outlive the account they concern for that period, on the same Art 17(3)(e) and Art 6(1)(f) grounds as the reports themselves. |
| Record of a hidden photo (Section 3.7b) | Kept under your own account for as long as the account exists, so that a photo that was hidden can be put back and so that a decision about it can be shown to you; erased when you delete your account. The photo itself is never deleted merely for being hidden. |
| Date of birth / age-gate record | Kept while your account exists (age-assurance evidence); erased with the account. |
| Encounter & ML/connection-outcome rows about other users | On your deletion these are stripped of your name and photo and your identifier is replaced with a placeholder, rather than the rows being deleted, so other users' history and counts survive. Be aware that one of those placeholders is currently built from your account's internal ID rather than being a fresh, unlinkable token — so it is not the dead end we would like it to be. Fixing that is [planned]; see Section 10. |
| Blocks placed on you by other users | Kept as long as the blocking user's account exists, so that their block continues to work — and removed when you delete your account, since the erasure cascade scrubs you from other people's block lists. |
| Technical logs, rate-limit and security data | Our limit is 30 days from the date of the log entry, and up to 6 months for logs retained for a specific abuse or security investigation. [not yet automatic]. |
| Crash, performance and analytics data (Section 3.11) | Retained by Google: Crashlytics 90 days; Performance Monitoring 30 days where associated with an IP address and 60 days where associated with an installation. These are enforced by Google, not by us. |
| Premium purchase records (Section 3.14) | Kept while your account exists; erased when you delete your account. Apple and Google keep their own billing records under their terms. |
| Advertising data (Section 3.13) | Held by Google under its own retention policy (https://policies.google.com/technologies/retention). Your consent choice stays on your device until you change it or remove the app. Flybi keeps no ad data beyond the placement counts in the analytics row above. |
| Backups | Our backup rotation is 30 days. A deleted record may survive in a backup until that backup is overwritten in the ordinary cycle; it is not used for any other purpose in the meantime, and if a backup is ever restored the deletions are replayed against it. |
Timing of erasure. When you ask us to erase data, or delete your account, we act on it promptly — the deletion runs when you confirm it, not on a clean-up schedule, and well inside the one month Art 12(3) gives us to respond. That is deliberately a different clock from the periods in the table above, which is why the box above tells you which of those periods are not yet enforced by a job.
Where a period above depends on something we cannot predict — an open safety investigation, a legal claim — we keep the data for as long as that specific matter requires and no longer, and we will tell you the expected period if you ask (Art 13(2)(a)).
9. Access to your device (ePrivacy) — Art 5(3) ePrivacy Directive / cookiebekendtgørelsen § 3
Three things Flybi does count as storing information on, or gaining access to information stored in, your terminal equipment under Art 5(3) of the ePrivacy Directive 2002/58/EC, transposed in Denmark as BEK nr 1148 of 9 December 2011 § 3:
- Reading your device's location and sending it to our servers — for discovery and background updates (Section 3.4) and the live game (Section 3.5). Sensor readings are outside Art 5(3) only while they stay on the device; once the reading, or any derivation of it such as a geohash, leaves the device, Art 5(3) applies (EDPB Guidelines 2/2023 v2.0, §44).
- Writing and reading the installation identifiers used by Crashlytics, Performance Monitoring and Analytics (Section 3.11). ⚠️ Those identifiers are currently being written at launch without asking you first — see the box at the top of Section 3.11. The rule below is the rule; we are not yet meeting it for this second item, and the consent prompt that will fix it is being built.
- Ads on the free plan (Section 3.13). The Google Mobile Ads software reads the device's advertising identifier, and stores and reads identifiers and your consent choice on the device. When advertising is on, Google's consent message asks you before the first ad is requested, and on iOS Apple's tracking prompt is shown as well. If you decline, ads are not personalised; declining does not remove ads.
All of these require your prior consent, and this is a separate legal hook that sits in front of our GDPR Art 6 basis — if we do not clear Art 5(3), no Art 6 basis can rescue the processing, and Art 5(3) has no legitimate-interest option. We do not rely on the "strictly necessary for a service you explicitly requested" exemption for any of it. In particular, that exemption cannot cover collection that continues while the app is closed, and it cannot cover crash reporting or analytics, because the test is what is strictly necessary from your point of view — Flybi works the same without them.
The operating-system permission dialog is not this consent. An OS permission prompt is a technical control over a resource; it does not name a purpose, a retention period, a recipient or a withdrawal right, and it cannot be a valid consent on its own. Our own in-app consent screen is what asks you, and the OS prompt is only triggered after you have said yes there. If you decline in Flybi, we do not show you the OS prompt at all.
Withdrawal. Turn location off in Profile → Location — one tap, at the same depth as switching it on. You can additionally revoke the permission in your device settings. Turning location off in-app stops every location read, foreground and background, and also erases the location already stored for you, both the copy on your profile and the private copy (Section 3.4). Withdrawing leaves the rest of Flybi working. For diagnostics and analytics there is no in-app switch yet (Section 3.11); until there is, e-mail us and we will stop it for you. For ads, Profile → Privacy & Ads → Manage ad consent reopens your choices.
Supervision. GDPR matters are supervised by Datatilsynet; Digitaliseringsstyrelsen supervises the Danish cookiebekendtgørelse — the rules in this section — and can impose penalties under it. See Section 11.
10. Your rights — GDPR Art 13(2)(b)–(d)
You have the following rights over your personal data. To exercise them, use the in-app controls described below or contact us (Section 1).
- Access (Art 15) — a copy of your data.
- Rectification (Art 16) — correct inaccurate data; you can edit most of your profile in-app.
- Erasure / "right to be forgotten" (Art 17) — delete your account from
within the app (Settings → Delete account). This triggers a server-side
cascade (
deleteAccountCloud Function) that erases your profile and everything filed under it — tags and tag images, personality, badges and preferences, date of birth, location (both the profile copy and the private one), your stats and streaks, your soulmate connections and secret-tag overlaps, your encounters, reveal requests in both directions, rate-limit records, waitlist entry and your notification tokens — plus every file you uploaded to our storage (including the images you sent in chats, #1021), and finally your Firebase Authentication record, deleted last so the process can never leave you half-deleted. It also strips your name and photo from records that live on other users, and removes you from other people's block lists. It also replaces your e-mail address on every chat room you took part in and on every message you sent that stays in someone else's conversation, with a random token created for that one deletion, so the address is no longer readable there, including in open rooms. Where your identity is kept on records that belong to other people, such as their encounters, it is replaced by a fixed "deleted user" placeholder that cannot be linked back to you. What it does not reach — plainly: - Copies in our analytics warehouse are deleted within 30 days, not at once. Crash reports and usage analytics are tied to your account's internal ID, and Google exports them, together with the history of your encounter records, to our BigQuery dataset once a day (Section 6.2). A recurring job deletes everything there that belongs to your account after each export, for as long as new copies can still arrive, and we keep a record that it happened and when, not what was deleted. In practice it is done within a day or two; we promise 30 days so a failed run can be fixed in time. Google's own copies inside Crashlytics, Performance Monitoring and Analytics expire on Google's schedule (Section 8).
- Messages you sent that were already delivered to other people stay in their conversations (Section 8), and safety and moderation records are kept for the period in Section 8 under Art 17(3)(e).
A separate deactivation option lets you hide your account without deleting it.
- A web-based deletion request is also available for users who have uninstalled the app, at https://flybi.app/delete-account (which names the app/developer, as required by Google Play's account-deletion policy) (live and published — #725).
What "delete your account" does, and what "clear chat history" does — they are not the same. Deleting your account really deletes data, as described above. The control still labelled "Clear chat history" deletes nothing: it records a point in time against your e-mail address on that conversation and hides everything before it from your own view. Everyone else in the room still sees every message, and the messages remain in our database. We are renaming the control, because the current name promises deletion and delivers hiding. If you want data gone rather than hidden, delete your account or ask us. - Restriction (Art 18) — ask us to stop using your data while a dispute about its accuracy or our legal basis is resolved, instead of deleting it. Hiding a conversation from your own view is a form of restriction, not erasure — see above. - Objection (Art 21) — object to processing based on legitimate interests (Sections 3.7, 3.10 and 3.12); we will stop unless we have overriding legitimate grounds (e.g. ongoing safety/abuse handling). - Data portability (Art 20) — receive data you provided, based on consent or contract, in a structured, commonly used, machine-readable format. - Withdraw consent (Art 13(2)(c); Art 7(3)) — where we rely on consent, you can withdraw at any time, as easily as you gave it, without affecting the lawfulness of processing before withdrawal. We rely on consent for: - Foreground location and, separately, background location (Sections 3.4 / 3.5) — withdraw either in Profile → Location, or in your device settings. Withdrawing also erases the location already stored for you, and the same screen has a standalone "Erase my stored location" control. - Crash & performance diagnostics and, separately, usage analytics (Section 3.11) — the in-app switches are [planned] and not there yet, so for now withdraw by e-mailing us and we will switch it off for your account and delete what has been collected. - Your tags, where they reveal special-category data (Section 3.3), and optional profile fields — withdraw by removing them or editing your profile. - Personalised ads and the device access they need (Sections 3.13 and 9): withdraw in Profile → Privacy & Ads → Manage ad consent, and on iOS also in Settings → Privacy & Security → Tracking. Ads then continue, not personalised.
Withdrawing any one of these leaves the rest of Flybi working. We do not make access to the app conditional on background location, diagnostics or analytics, and we will not re-ask after you have refused.
Access and data-portability requests are handled via the contact e-mail in
Section 1 (support@flybi.app), with a response target of within one month as
required by Art 12(3). (Current process; to be confirmed in a professional
review as the project grows.)
11. Right to complain — GDPR Art 13(2)(d)
If you believe we have processed your data unlawfully, you may lodge a complaint with the Danish supervisory authority. You do not need to raise it with us first, though we would rather you did.
Datatilsynet (Danish Data Protection Agency) — https://www.datatilsynet.dk — supervises our compliance with the GDPR. Its current postal address and complaint channel are published on datatilsynet.dk; refer to the site for the authoritative details.
Digitaliseringsstyrelsen (Danish Agency for Digital Government) — https://digst.dk — supervises the Danish cookiebekendtgørelse (BEK nr 1148 of 9 December 2011), which is the rule that governs access to information on your device: our reading of your location, and the installation identifiers used by crash reporting, performance monitoring and analytics (Section 9). Complaints about those go to Digitaliseringsstyrelsen rather than Datatilsynet. Digitaliseringsstyrelsen is also Denmark's Digital Services Coordinator under the Digital Services Act.
You may also complain to the supervisory authority in your EU/EEA country of residence.
12. Accountability records we maintain (informational)
For transparency, and because the Art 30(5) "<250 employees" exemption does not apply to us (our location processing is not occasional and is likely to result in a risk to data subjects — these are alternative triggers, any one of which removes the exemption), we maintain a Record of Processing Activities (ROPA) under Art 30(1).
A Data Protection Impact Assessment (DPIA) under Art 35 is mandatory for our location processing. The route is not "large scale" — at our current size we do not meet the Art 35(3)(b)/(c) scale triggers — but Datatilsynet's own Art 35(4) list, item 3: processing of location data in combination with at least one further criterion. We process location data and meet at least two further WP248 rev.01 criteria (systematic monitoring, and sensitive or highly personal data). That list item carries no size threshold, so a closed beta of 26 users does not escape it. The DPIA covers the foreground/background split and why background collection is necessary, the Art 9 analysis, the sampling frequency and stored precision, retention, the outing / stalking / physical-safety risk model, processors and transfers, and withdrawal and deletion mechanics. If a high residual risk remains after mitigation we will undertake Art 36 prior consultation with Datatilsynet. The ROPA and DPIA are maintained on file.
13. Security & data breaches
We protect your data with measures including encryption in transit, Firebase
Authentication, server-side security rules (firestore.rules) and rate limiting.
App Check is integrated but its enforcement is currently off on our
server functions (Section 3.10), so it is not adding protection today. No system
is perfectly secure, and Sections 3.4, 3.5, 6.1 and 10 name the specific places
where our current rules are looser than we intend them to stay.
If a personal data breach occurs, we will notify Datatilsynet without undue delay and, where feasible, within 72 hours of becoming aware of it, unless the breach is unlikely to result in a risk to your rights and freedoms (GDPR Art 33), and we maintain an internal breach register (Art 33(5)). Where a breach is likely to result in a high risk to you, we will inform affected users without undue delay (Art 34). Because a breach affecting precise location, chat and identity could be high-risk (per EDPB Guidelines 01/2021 breach-severity factors: nature/sensitivity/volume of data, ease of identification, and severity of consequences), we treat such incidents accordingly.
14. Future features (not active)
The following are not part of the live service and are listed only so this notice stays accurate as the app evolves:
- Biometric / face-comparison identity verification — deferred. If introduced, biometric data used to uniquely identify you is special-category data (Art 9) and will require Art 9(2)(a) explicit consent, a strengthened DPIA, and an update to this notice before any processing begins. We do not process biometric data today. (A non-biometric "verified" trust badge exists, decided by a human moderator; any verification artifacts are kept in a private collection not exposed in discovery.)
15. Changes to this policy
We may update this notice. We will post the new version at https://flybi.app/privacy and, for material changes (e.g. a new processing purpose or legal basis), notify you in-app or by e-mail and, where required, seek fresh consent.
*Drafting note for counsel: every legal requirement above is grounded in the
research brief and in the external legal research memo of 7 August 2026
(MEMO.md) — GDPR Arts 3, 5, 6, 7, 8, 9, 12, 13, 17, 18, 21, 22, 25, 27, 30, 33,
34, 35; ePrivacy Art 5(3) + EDPB Guidelines 2/2023 v2.0 §44, transposed as BEK nr
1148 § 3; Danish Data Protection Act § 6(2); e-handelsloven § 7. Data-flow
descriptions are taken from the live code (firestore_fields.dart,
firestore.rules, discovery_repository_impl.dart, chat_room_game_wrapper.dart,
the deleteAccount Cloud Function, and the moderation runbook). The first
revision of 7 August 2026 brought the notice into line with the memo on:
background location and the Art 9 condition (§3.4, §3.5, §9),
Crashlytics/Performance/Analytics as consent-gated device access (§3.11),
event-anchored retention (§8), the honest account of chat clearing versus
deletion (§3.6, §10), and controller contact details (§1).
The second revision of the same day reconciled the notice against a
line-by-line source-code audit (code-audit-2026-08-07.md), and the code won
every disagreement. Corrected: the reach and the gaps of the deletion cascade
(§10, §8); the App Check claim (§3.10, §6.2, §13); world-readable profile e-mail
and coordinates (§3.4, §6.1); what an open-room listing actually delivers and how
much backlog a new joiner sees (§6.1); telemetry running by default rather than
on consent, with the Flybi user ID and, in one path, an e-mail address attached
(§3.11, §7, §9, §10); published retention periods that no scheduled job enforces
(§8); the live-position record left behind by the Hot/Cold game (§3.5); the
"clear chat history" watermark (§3.6, §10); and the client-side-only age gate
(§3.8). Passages describing a design that is not yet shipped are marked
[planned]; that marker is load-bearing and must not be removed ahead of the
code.
The open questions behind those markers — founder decisions, and points the audit
listed as not determined — are tracked internally in
docs/legal/open-items-2026-08-07.md and in
#1167. They are deliberately
kept out of this file: tool/build_site.py renders this document to
https://flybi.app/privacy, and markdown passes HTML comments through to the
published page.*