Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Mixtape Manifesto

Avatar for Marina Coelho Marina Coelho
September 08, 2026

The Mixtape Manifesto

Avatar for Marina Coelho

Marina Coelho

September 08, 2026

More Decks by Marina Coelho

Other Decks in Technology

Transcript

  1. The Mixtape Manifesto Building an AI peacekeeper for the streaming

    wars Marina Coelho Tim Condon DRE at Google Vapor Core Team
  2. A friendship that started with music Tim and Marina already

    knew each other from a few conferences that they attended and spoke at in the past. But one day, at SwiftConf in 2022, they found out something very important: They were both emo!
  3. The platform wall • The core problem: The dreaded "link

    incompatibility" in group chats. • Spotify vs. Apple Music: Sending a Spotify link to an Apple Music user creates immediate friction. And vice versa. • The broken flow: Users are forced to manually search for the song on their respective platform. Spotify Source URL ❌ Apple Music Target URL
  4. Turn frustrations into features • Spot the friction: The best

    app ideas hide in everyday annoyances. • The philosophy: Don't ignore tiny hurdles; build a bridge over them. • Be creative: Transform a daily complaint into a weekend side project. A thousand app ideas are waiting in your daily routine!
  5. Letʼs try it together! • Open the Daily Friction Challenge

    using the QR Code • Submit as many daily friction points as you'd like via the tool
  6. The 48-hour journey 1. Brainstorming: What should this app look

    like? What tools do we need? 2. PRD Prompt Gemini to create a Product Requirement Document 3. Build: Ask Antigravity Marina and Claude Tim to vibe code the app 4. Test: Upload app to Testflight, test on real devices and spot problems 5. Fix problems: Fix problems and upload new version to Testflight 6. Iterate: Repeats steps 3 to 5 until weʼre happy with the app!
  7. The 48-hour 6-hour journey 1. Brainstorming: What should this app

    look like? What tools do we need? 2. PRD Prompt Gemini to create a Product Requirement Document 3. Build: Ask Antigravity Marina and Claude Tim to vibe code the app 4. Test: Upload app to Testflight, test on real devices and spot problems 5. Fix problems: Fix problems and upload new version to Testflight 6. Iterate: Repeats steps 3 to 5 until weʼre happy with the app!
  8. Brainstorming the UI • A minimalist, 1-on-1 messaging app dedicated

    solely to music links. ◦ • The send button should be disabled if the message is not a link! Primary flows: ◦ Add your friends to your contact list. ◦ Start a chat with your friend and send the link to a song on either Spotify or Apple Music. ◦ Chat screen is populated with a simple card with album art and two buttons: one to Spotify and one to Apple Music.
  9. Minimalist screens 01 / Minimalist UI Contact List 941 941

    Contacts + Add < Back Sarah J. Pending Requests 1 03 / Real-time sync The Chat Thread Check out this album! Dave Miller Wants to connect After Hours Active Contacts Sarah Jenkins 02 / Native flow iOS Share Sheets The Weeknd Spotify Apple Music Active now • Listening Alex Rivera 04 / Absolute intent This is insane! 🔥 Last sent 2h ago James Carter Offline Paste music link to chat... Regex Locked
  10. High impact cards Midnight City M83 Hurry Up, We're Dreaming

    ▲ AUTOLINKED Open in Spotify Apple Music
  11. Brainstorming the architecture • How are we handling chat storage?

    • How are we handling user authentication? • How do we alert users about new messages? Or new contact requests? • How are we keeping our backend resources safe? • Are we supporting other listening platforms beyond the ones we use? • Are we supporting other clients Android / Web)? • Letʼs use Gemini to do the link conversion!!!
  12. Architectural decisions • Chat storage: We need real time sync

    and offline support • Authentication: We need to allow users to sign in with email • Updates: We need notifications Platform and client MVP Intentionally limited to Spotify and Apple Music for the MVP. MVP only available for iOS. ◦ FIREBASE!!! • Which we need to trigger on the server side Security: We need to protect our resources from abuse
  13. The Firebase suite BUILD Authentication App Check SQL Connect database

    Hosting App Hosting Cloud Functions for Firebase Firestore database Realtime Database Cloud Storage for Firebase Firebase AI Logic
  14. The Firebase suite RUN Test Lab App Distribution Remote Config

    A/B Testing Crashlytics Performance Monitoring Cloud Messaging Google Analytics
  15. Chosen services Database Identity Updates Updates Security Cloud Firestore Firebase

    Auth Cloud Messaging Cloud Functions App No-SQL real-time database for chat history and contacts. Secure user sign-up and login. Send push notifications for new messages and contact requests. Automatically run backend code in response to events. Check Protect backend resources from abuse.
  16. Creating the PRD with Gemini Gemini created a PRD with

    all the necessary information. Some highlights: Screen 1 Contact List Screen • • • Contact List: Displays active contacts. Tapping a contact opens the chat screen with that user. Add Contact Modal: Tapping + opens a prompt to type another user's email address. Contact Requests Section: Displays pending incoming requests Accept / Reject buttons). Sending a request creates a pending notification/record in Firestore for the recipient.
  17. Creating the PRD with Gemini Gemini created a PRD with

    all the necessary information. Some highlights: Screen 2 Chat Screen Link-Only Thread) • • • Message History: Real-time Firestore stream of previous link exchanges. Link-Only Composer: ◦ Message input field only accepts valid URL patterns (open.spotify.com or music.apple.com). ◦ The Send button remains disabled until regex validation confirms a valid Spotify or Apple Music URL pattern. Mixtape Card Component: ◦ Album artwork (AsyncImage). ◦ Song Title & Primary Artist. ◦ Dual Action Buttons: "Open in Spotify" & "Open in Apple Music".
  18. Creating the PRD with Gemini Gemini created a PRD with

    all the necessary information. Some highlights: Extension: iOS Share Sheets • Allows users to tap "Share" inside Spotify or Apple Music, select Mixtape, pick a contact from a swift launcher sheet, and dispatch the link directly.
  19. Building the app with Antigravity PRD  Antigravity → Firebase

    MCP  Firebase Agent Skills → App • firebase.google.com/docs/ai-assistance/mcp-server • firebase.google.com/docs/ai-assistance/agent-skills
  20. Main screen • Contacts: Clean interface to view active connections.

    • Invites: Quick flow to add and accept new friends.
  21. Chat screen • Chat: A dedicated space for song links

    exchange. No other messages allowed. • Cards: Links are automatically expanded into UI cards with buttons to both listening platforms supported.
  22. Share screen • Native integration: No need to copy-paste your

    links, you can send tracks via native iOS share sheets.
  23. Notifications • FCM Responsible for delivering push notifications to the

    app. • Cloud Functions: Once the user sends a song or adds someone as a contact, it triggers a Cloud Function to send a push notification to that contact.
  24. Testing the app While testing our app for the first

    time, we had some interesting findings: • Firebase Authentication was working perfectly! • The flow to add a contact worked well and was easy to complete. • The collections and documents created in Firestore were indeed following what we had established in the PRD. • App Check code was implemented correctly. • But the link conversion and album cover were not working :(
  25. The link conversion problem • Gemini had some hallucinations when

    converting the link to another platform. • We tried different prompts and different models, but it still didnʼt work. • So we went the “traditionalˮ way: using Spotify and Apple Music web APIs! • Well… not that traditional, since we used Claude to implement that!
  26. Spotify and Apple Music APIs • We donʼt need an

    API key to query iTunes for metadata! • As for Spotify: ◦ You need to have a premium account ◦ Sign in to Spotify for Developers with that account ◦ Register your app and select "Web API" for the question asking which APIs are you planning to use ◦ Copy the access token generated for your app and use it in your API requests
  27. Sign Up Flow let result = try await Auth.auth() .createUser(withEmail:

    email, password: password) let uid = result.user.uid let newUser = AppUser(...) try db.collection("users").document(uid).setData(from: newUser) self.currentUser = newUser
  28. Sign In Flow let result = try await Auth.auth() .signIn(withEmail:

    email, password: password) if let userEmail = result.user.email { fetchUserDocument(uid: result.user.uid, email: userEmail) } // fetchUserDocument() let doc = try await db.collection("users") .document(uid).getDocument() if let appUser = try? doc.data(as: AppUser.self) { self.currentUser = appUser }
  29. Fetch Conversation Flow final class FirestoreManager { private var db:

    Firestore { return Firestore.firestore() } /// ... var messages: [Message] = [] }
  30. Fetch Conversation Flow func startListeningMessages(for conversationId: String) { messagesListener =

    db.collection("conversations") .document(conversationId) .collection("messages") .order(by: "timestamp", descending: false) .addSnapshotListener { [weak self] snapshot, error in guard let self = self, let documents = snapshot?.documents else { if let error = error { print("Error listening messages: \(error)") } return } self.messages = documents.compactMap { try? $0.data(as: Message.self) } } }
  31. Save Link Flow let metadata = try await MusicLinkResolver.resolve(url) let

    msgId = "MSG_\(UUID().uuidString.prefix(8))" let message = Message(id: msgId, senderUid: senderUid, timestamp: timestamp, originalUrl: url, metadata: metadata) try db.collection("conversations") .document(conversationId).collection("messages") .document(msgId).setData(from: message)
  32. Push Notifications Flow Part 1 exports.notifyOnMixtape = onDocumentCreated( { document:

    "conversations/{conversationId}/messages/{messageId}", }, async (event) => { // Get all the data... });
  33. Push Notifications Flow Part 2 await getMessaging().send({ token, notification: {

    title: `${senderName} sent you a mixtape 🎵`, body, }, data: { conversationId }, apns: { payload: { aps: { sound: "default" }, }, });
  34. Key takeaways Embrace friction Embrace AI Human in the loop

    Everyday annoyances are the best blueprints for side projects. Use AI as a pair programming buddy. ALWAYS check your code and test your apps thoroughly.