DEV Community

KevinTen
KevinTen

Posted on

The 6th Attempt: When Your AR Dreams Meet the Brutal Reality of User Testing

The 6th Attempt: When Your AR Dreams Meet the Brutal Reality of User Testing

Honestly? I never thought I'd be here again. Writing the sixth article about the same AR project that still has zero stars on GitHub. But here we are - the spatial-memory project lives on, not because it's successful, but because my stubborn refusal to let it die (and maybe my even stronger addiction to writing about failure).

The Spark That Started It All

It all began with this brilliant idea: what if we could pin multimedia memories to real-world locations? Think digital time capsules - you could leave a voice message at your favorite coffee shop, a photo at your first apartment, a video at the spot where you proposed. Beautiful, right? The kind of idea that makes investors' eyes light up and developers start coding before the business plan is even written.

So I built it. Java Spring Boot backend for the API, JavaScript WebXR for the AR rendering, AWS S3 for multimedia storage, a spatial database for the GPS magic. I was so proud of those 2,000 lines of "advanced" code that supposedly made this revolutionary app work.

The First Punch in the Face: GPS Reality Check

Here's the thing nobody tells you about GPS accuracy: it's not as accurate as you think. In my dreams, I was placing memories with surgical precision - right on the exact spot where something meaningful happened.

Reality? In open areas, GPS is accurate to about 3-5 meters. In cities? Good luck, you're looking at 20-30 meters. That's the size of a freaking building! So much for "pinpoint accuracy."

@Controller
@RequestMapping("/api/memories")
public class MemoryController {

    @PostMapping
    public ResponseEntity<Memory> createMemory(@RequestBody MemoryCreateRequest request) {
        // The harsh truth: this location is probably within 20-30 meters of accuracy
        GeoLocation location = request.getLocation();
        System.out.println("User thinks they're at " + location.getLatitude() + ", " + 
                          location.getLongitude());
        System.out.println("Reality: they're somewhere within a 20-30 meter radius");

        // Store it anyway, because what choice do we have?
        Memory memory = new Memory();
        memory.setLocation(location);
        memory.setContent(request.getContent());
        memory.setMediaType(request.getMediaType());

        return ResponseEntity.ok(memoryService.save(memory));
    }
}
Enter fullscreen mode Exit fullscreen mode

This little piece of code? That's the sum total of my spatial database "innovation." Basic CRUD operations with laughably imprecise location data. And you know what? It's still more advanced than most of the solutions out there.

The AR Rendering Nightmare

Oh, the AR rendering. Let me tell you a story about expectations vs reality.

Expectation: Users open the app, see beautiful overlaid memories floating exactly where they should be, experience emotional nostalgia, become loyal users who tell all their friends.

Reality: Users' phones either can't handle WebXR, or the battery dies after 5 minutes, or the AR overlay is jittery and barely visible in anything but perfect lighting conditions.

// WebXR AR rendering - looks cool in theory, painful in practice
class MemoryARRenderer {
    async renderMemoriesAtLocation(location) {
        try {
            // First problem: device compatibility
            if (!navigator.xr) {
                throw new Error("Device doesn't support WebXR");
            }

            // Second problem: battery drain
            if (this.getBatteryLevel() < 20) {
                throw new Error("Battery too low for AR rendering");
            }

            // Third problem: performance issues
            const session = await navigator.xr.requestSession('immersive-ar');
            const referenceSpace = await session.requestReferenceSpace('local');

            // Try to render memories...
            this.renderMemories(session, referenceSpace, location);

        } catch (error) {
            // 90% of the time, we hit one of these error cases
            console.error("AR rendering failed:", error.message);
            this.showFallbackView(location);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

This code looks promising, right? In practice, it's a cascade of disappointment. Users get excited, try to use the app, and then encounter one technical limitation after another. After the third "This device isn't supported" message, even the most enthusiastic user starts to question their life choices.

The Database Horror Story

If GPS and AR weren't bad enough, let's talk about the database. My spatial database was supposed to be the crown jewel of the entire operation.

What I envisioned: elegant spatial queries finding memories within 10 meters of a user's location, efficient indexing, beautiful PostgreSQL spatial functions making everything work perfectly.

What I got: a data structure that couldn't handle the simple reality of mobile networks, battery constraints, and user expectations.

-- What I thought would work
SELECT * FROM memories 
WHERE ST_Distance(location, ST_MakePoint(user_lat, user_lng)) < 0.01
ORDER BY created_at DESC LIMIT 10;

-- What actually happens in production
-- Network latency makes spatial queries painfully slow
-- Users move too fast for static spatial indexes to be useful
-- Battery drain forces app to limit frequency of location updates
Enter fullscreen mode Exit fullscreen mode

I spent weeks optimizing those spatial queries, going from 47 seconds down to... still way too slow for mobile users. The solution? I basically gave up on sophisticated spatial indexing and went with a simpler approach that still wasn't great but was slightly less terrible.

The Business Reality Check

Here's the most brutal part: 200+ hours of development, 20 real users, $0 in revenue.

Let me repeat that: 200+ hours of my life poured into this project, 20 actual people have used it more than once, and I've made zero dollars.

And yet, somehow, I'm still writing about it. Why? Because maybe there's value in the failure itself. The lessons learned, the skills gained, the sheer entertainment value of watching someone stubbornly pursue an idea that clearly wasn't working.

The pros that actually matter:

  • I learned advanced mobile development skills
  • I gained experience with geospatial databases
  • I understand AR/VR development limitations better than most
  • I can optimize mobile battery usage (out of necessity)
  • I have a deep appreciation for user testing and market validation

The cons that hurt:

  • Wasted 200+ hours that could have been spent on something with actual demand
  • Built features nobody wanted (advanced AR rendering when basic location services would have been sufficient)
  • Chased a "vision" instead of solving real problems
  • Created technical complexity that drove users away
  • The emotional toll of seeing your passion project flop

The Unexpected Lesson: Simple Wins Again

After trying to build this "advanced" AR system, I learned something profound: simple beats complex every time.

Users didn't want sophisticated AR overlays. They didn't need 3D memory visualization. They just wanted a simple way to remember places that mattered to them.

What if I had built that instead? A simple app that let you:

  1. Take a photo at a location
  2. Add a text note
  3. Come back later to see your memories

No AR, no spatial database complexity, no battery-draining rendering. Just simple, useful functionality.

// What I should have built from day 1
@Service
public class SimpleMemoryService {

    public Memory saveSimpleMemory(Location location, String note, byte[] photo) {
        Memory memory = new Memory();
        memory.setLocation(location);
        memory.setNote(note);
        memory.setPhoto(photo);
        memory.setCreatedAt(LocalDateTime.now());

        return memoryRepository.save(memory);
    }

    public List<Memory> findMemoriesNearby(double lat, double lng, double radiusKm) {
        // Simple distance calculation - good enough
        return memoryRepository.findByLocationNear(lat, lng, radiusKm);
    }
}
Enter fullscreen mode Exit fullscreen mode

This? This would have taken me a weekend to build and would actually solve a problem people care about. But no, I had to chase the "AR revolution" and build the "next big thing."

What I'd Do Differently

Looking back, here's the honest truth:

  1. Start with user interviews first - I should have talked to potential users before writing a single line of code
  2. Build the simplest possible version first - Minimum viable product, not maximum complexity
  3. Validate the core assumption - Do people actually want to pin memories to locations?
  4. Focus on real problems - Not "cool technology" problems
  5. Test early and often - Instead of waiting until the end to see if anyone cares

The Meta-Realization: I Became the Expert

Here's the twist: by failing so spectacularly at building this AR app, I actually became an expert in mobile development limitations, AR rendering challenges, and the gap between ambitious ideas and practical reality.

The irony isn't lost on me - I'm making more content about my failed project than I ever made from the project itself. Maybe that's the real business model here: document your failures thoroughly enough, and they become valuable case studies for others.

The Interactive Question

Now I'm genuinely curious - what's your biggest "I should have known better" development story? Were you ever so passionate about an idea that you ignored all the warning signs? Or did you manage to pivot from complex to simple and actually succeed?

Let me know in the comments - I'm collecting stories for what might become my next project: "Failed Developer Stories: The Reality Behind the Hype."

After all, if I'm going to be the world's leading expert in failed AR applications, I might as well expand my portfolio.

Top comments (0)