Hi, thanks for listening. This is the It's So Widget's Flutter Podcast. My name is Hillel Korn. In each episode, you get the chance to speak with another amazing member of the Flutter community. In this episode, we're extremely lucky to speak with Dan. Welcome. Hi, thanks for having me on. I really appreciate this. Thanks for being on the podcast. So to start, do you want to share a bit about your background? Yeah. Well, I guess the main reason I'm here is to talk about an app that I built called RunPee.
that is an app that tells you the best time to pee during a movie so you don't miss the best scenes. And that's, I guess, my claim to fame. I'm a philosophy and history major that spent very little time reading philosophy and a lot of time learning JavaScript and CSS back in the 90s. And that just evolved into...
Little like working on websites and stuff for companies in the early 2000s. And then I worked for Microsoft Xbox as a Flash prototyper. So that was really fun being a Flash developer at Microsoft. Not too many of those. And then I quit Microsoft to become a freelance developer and then
decided like i need something that's gonna you know enhance my portfolio and i need to learn mysql and some php and i've never built a data-driven app so i thought you know i've had this run p idea it's stupid but yeah i think i'll just build that and um
It just took off, like surprised me as much as anybody else. And that's been my primary source of income ever since. That's an awesome story. That's really cool. I'm curious. So when you first launched the app, was it almost an instant success or was there a process to build a user base? Yes and no. So this is 2008, August of 2008. I built, it was literally a web application built with Adobe Flex.
I mean, like I said, 2008, there just weren't that many...
mobile apps yet. And, uh, I built it and I went to a developer, the flex, the 360 flex conference in San Jose that year. And they let me get up on stage and talk about it. And everybody was just like, Oh my God, that's so awesome. And then crickets, like, you know, I go home and, you know, like two people a day are using the site. And, um,
It was originally kind of a Wikipedia users could submit when they thought would be a good time to pee during a movie. And that was my initial thought, that this is the way this would work. And a lot of people, developers especially, when I explain how the app works, they think that it's user-generated content. But it turns out that
The data needs to be so precise. You know, we need to know exactly when and exactly what happens. So we actually have to go watch all of the movies ourselves. So that's, you know, good and bad. But yeah, so for 2008 into spring of 2009, it was just kind of like languishing.
And I thought, you know, I'm going to give this another chance. And I started going to see movies pretty frequently to have like a, you know, a full database of recent movies in there. And that's when Star Trek 2009 came out and social media was just beginning to kind of grow. And I put in P times for that movie and,
And I had a anti-pee time at that time. A lot of people who saw the movie, you kind of intuitively have this sense of when you can pee during a movie. And when Kirk lands on that ice planet, people are like, oh, I think this is a good time. And so they ran to the restroom.
And then they come back and Kirk is talking to original Spock. And they're like, wait, what? What's going on? And so they were completely lost. Like, hey, there's this app that would have told you don't go pee at this time. And that kind of kicked off a lot of discussion. And I built a mobile app as quickly as I could that launched on July 4th of 2009.
And from there, it's just kind of taken off. Very cool. It sounds like it was a journey toward finding product market fit, which is really interesting and a good lesson for many people. I've had a number of side projects I've worked on where I'm kind of looking back, feel I've had to push a bit harder and not give it up so early. Maybe I'm more successful. It's interesting, you kind of have expectations of how users will behave, and it doesn't always match reality once you ship the product and see if people use the app. Right. Yeah, that is such a key aspect.
of finding just a few users who can become your evangelists and when to pull the plug and say, okay, yeah, this is just never going to gain traction or is it just a matter of time? Nobody's got an answer to that. There's a lot of things that have succeeded and I think they did so just because they caught fire at just the right time.
A lot of things have failed, but they could have been successful in the right environment. And you just never know.
I think what's nice about Run-P is you have a monopoly, which is wonderful, right? In the startup market field, that's kind of what you want. That if people want to know when to run P, you're the guy. Come to your app. It is. There was actually a competitor back in 2012-ish, 13? Oh, no. Did they copy you as an imitator? Yeah, they totally copied. It was actually called P-Run instead of Run-P. I didn't find out about it until...
Someone contacted me on support and they're like, oh, the app isn't updating, the movies aren't right, and all this mess. And they're describing it to me like, that's not possible.
And I'm like, can you send me a screenshot? That's not even my app. I'm doing tech support for somebody else's app now. And I think they kind of caught on that it was a lot more work than they thought it was going to be. I think they say imitations of highest form of flattery. Exactly. Yeah. So they kind of fell off the map. And I have been worried a little bit here and there that IMDB could totally just like, oh, pfft.
We're just going to throw $100,000 at this and knock it out of the park, and everybody's going to use our version. And they've never done that. And we are actually... Our Run-P data is licensed by AMC Theaters. And so if you use the AMC Theater app, you can go in there and find the P-Times as well. There's the Run-P logo, and their version of it is very...
uh clumsy uh compared to the app but it gives you the essential so that's really interesting uh yeah i think it's one of the great fears of many startup developers where you kind of want to hit this middle road where you obviously want some success but when you're too successful it kind of become its own problem then you become more of a target yeah for sure you know and um yeah i don't know what to say like it's it's something that everybody faces so we're all in the same boat um
just do better. I think that two keys to RunP's success are, A, that it's a fun story to tell. So from our users just tell me all the time, like I share this with my whole family, I share this with people at work, completely unprompted. And I'm sure that everybody listening to this could well imagine that even if you don't use the app,
If you're happy to talking to a group of friends about movies and you're like, oh my God, I got to tell you about this app because it gives you the center of attention. It feels good to share fun, useful information. And it's not really controversial. Like,
nobody's going to say like, Oh, I believe totally differently. Like, you know, I'm on the other side of that. That's politically, that doesn't work with me or whatever. It's like, that's not going to happen. So yeah, it's just a fun sort of share. And it's not just our users like CNN shared run P on the homepage of their entertainment site and crashed the server right when infinity war came out. So yeah,
Yay, but shit. Right. I love movies. I'm a huge movie fan. I love long movies. Well, that's good. You're right in our demographic. Right.
is making it very easy to interface with our users. So we share our Twitter account and we've got a Facebook account that somebody else manages because I got off of that.
But like I respond to everything on Twitter. If you mentioned RunP, you know, I'll at least heart it and show you that, yeah, I did hear you or it's a question. I always get back. I respond to every single email that we get. And I also make it really, really easy for users to email me directly from within the app.
And it's got the context of where they are in the app. So a really common thing is, you know, we make mistakes with the synopsis. Maybe it's we use the wrong character, said such and such, or it could just be a typo. And right there on the screen, when you're reading the synopsis of a P time,
I guess I should have gone into the details of how the app works, but there's these P times and it tells you, you know, 43 minutes into the movie, you could run P when Sarah says, get out of my house, you know, so that's your cue. And if you do go to the restroom, then there's, you can,
tap to see the synopsis and read a brief summary of what's happening while you're away. And then right there at the bottom of the screen, it's like, hey, did you notice anything wrong? Any feedback? And they can just say, so-and-so didn't say that. And
get back to me really easily. It already has all what movie they're watching, what pee time they're on. So I try to make it as simple as possible for the users to provide feedback, you know, and that's helped us get new features to meet their needs. So, you know, we added links to IMDB and Rotten Tomatoes because people like, hey, you know, that would be handy. And
That's a simple thing to add. And we added the anything extra because users are like, hey, could you let us know if there's anything during the credits? I mean, you're already watching the movie. So we added that feature and that's been hugely popular. Like a lot of people use the app just to see, is there anything extra during the movie? And there are other services that offer this, but theirs is kind of crowdsourced.
And we do a really good job of like specifically the credits are nine minutes long. There's two extra scenes. One of them's after about two and a half minutes, there's an extra scene. And then after the credits, there might be another one. Whereas the other services are just kind of like yes or no. And we provide all of that. The anything extra is there's no paywall to that. There's no advertisements for that. You could,
If you use the Run P app for that, you'll never see an ad and you'll never have to spend any money. It's a great feature. I would use the app alone just for that feature. There's nothing worse than sitting around for nine minutes of credits and then nothing on the blank screen. Right, right. And that's the reason we do it is some people do use it, like I said, just for that. And we don't make any money off of them, but they do have the app and they can be reminded to share it with somebody else. And so
So our pay model is you can use the app for free forever and just view advertisements. And you also get to choose would you see the advertisements because it would not be a good user experience if you're halfway through a movie and like, oh, I need a pee time.
And you open the app and there's a video playing in your face. It's like, oh, shit. You know what? So we let you choose when to see the advertisements. Or if you see a lot of movies and you want to support us and you don't want to deal with ads, then you could subscribe for a dollar a month. That's not for everybody, but it's there as an option.
Nice. That's interesting. And so at this point in the story of the company, you've developed a, used Flex to build the mobile apps. And then obviously we're here because we switched to Flutter. So I'd love to understand the thought process, both, you know, what made you switch and then why you chose Flutter?
Well, yeah, I hadn't been doing any freelance work throughout probably 2013 until 2020. I was living off of entirely the RunP app. And it was kind of itching to get back into the field. And there's just no call for Flex and Air anymore.
And also, I was concerned about the future of where Air was now that Harman had taken over. Just how well supported would it be? And the app could use a facelift. To me at the time, I'm a developer, I'm not a designer, and it looked okay to me. And now that it's been rebuilt in Flutter,
Oh my God. It's just like, I see pictures like screenshots of the old app and I'm like, Oh, how did I ever let it look like that? Like it looks so much better. And then obviously it's way more performant. And then more importantly to me, it's future-proof. Like I feel very confident that, you know, we could ride Flutter for at least a decade and never have to worry about like, you know, should we adopt to something, adapt to something new?
when it was time to choose a new framework. So first, it was definitely going to be cross-platform because I'm not going to build two apps. I've never been interested in that. And also, I'm not going to write JavaScript because I don't like JavaScript. I like typed languages. I don't like the HTML, CSS world. You know, every time I have to go and mess with my
WordPress blog for run P.com and I get into the CSS, I'm like, Oh, what a nightmare this is. And, you know, kudos to those who are experts at this. You hats off, but it's just not something I wanted to get into. And fortunately Flutter had just, uh, passed 1.0. Uh, my wife actually found it first and,
And she's like, this looks really interesting. And we researched it and we took a course at Udemy with Angela Yu, who was an amazing instructor. And then we rebuilt the app. And now since then, I've been doing some freelance work with Flutter just to help have some extra income.
Cool. And how has the user response been since releasing? Obviously, you're kind of switching the app. I assumed one version you updated and they went from the old app to the new app. Was there a positive response or any concerns? Yeah, yeah. Overwhelmingly positive. Like I said, it looks worlds better. It's still functionally the same app. The navigation didn't fundamentally change.
And so that was handy to users. I'd say one of the problems that I had, and I was really, really fortunate that I looked forward for this probably at least a year beforehand, is getting the data out of the databases for the local storage. Now, when you've got it, you think like, oh, you're in the same sandbox. So you just go open up those MySQL Lite databases
databases and blah, blah, blah. Everything's cool. And it's like not at all like that. What I had done is I'd stored in a text file the user's ID number. And that was easy to find. It was at the root of the sandbox. So when I moved over to Flutter, all I had to do was find that file. And I knew the user's ID number. And from their ID number, I could auto sign them in
And I didn't have to like try to, you know, figure out how to use the old data or anything like that could just seamlessly move over. And that was, it took a long time to iron out the bugs on that. Um, but yeah, that did make the transition for the vast majority of users. Uh, you know, they just one day open the app and also this happened over the pandemic. Um,
So very few people were updating per day. It was, you know, I actually still get people that are just now getting the new version and they're emailing me and they're like, oh my God, I love this. You know, when did this happen? Like, well, two years ago now, I think. So let's talk about the app itself. I feel every episode in this podcast, I was talking about state management. So did you use a package or how was the app built? Okay. So,
Coming from Flex, I had a system that I'd already built myself for state management. And I did when I was learning Flutter. And I really like that it's agnostic to state management. It doesn't shove it down your throat. So I tried Block and I tried GetX.
There's a couple of others that, you know, I don't remember the names of them, but, you know, like if you go read, if you Google, you know, Flutter state management top five, it's everybody's going to give you basically the top five. And I took them all for a test drive and didn't like any of them. Aside from the kind of default of just using set state and change provider, you
It's simple. I can follow the execution of code when I need to go find a bug. I don't get why block specifically because I've had to use it in other projects.
And I just don't get why anybody would use it, but to each their own, right? And yeah, and I also think that all the different options, I think many of us as developers model the code in our minds differently. So for example, some people like the event construct, that it's an event loop and the user's part of that loop by kind of clicking and tapping away, they're triggering events. And from that perspective, block kind of makes sense with use of streams and that flow of events.
But for simpler apps or other styles of apps, other patterns definitely make more sense. Yeah, I don't like passing data from one widget to another unless, you know, like from one to another, I can live with that. You know, obviously you build a widget and it needs to talk to its parent and that's cool. When you've got to pass along to multiples and you've got like the tree, it just feels like now...
each widget is kind of like locked into where it is. Like it's kind of hard to prune things. And maybe this is just that I didn't get to a really deep level of like using block for instance, but I like my view to know about the data, but the data to not know about the view, you know? So if, for instance, if anything like the user data changes,
then I can just send out a notifier. Hey, something about the user changed. And if I happen to be on a screen that might need to reflect that change, hey, let's just set the state again and get the new data. And if I'm not on a screen that has any user data, I don't care that the user data changed in the background. So that just seems the least amount of plumbing, I guess,
to me. Yeah. No, that makes a lot of sense to me. I think what I find with Flutter is if you drill down to the performance level, a set state can be less performant than other options. However, Flutter is so generally performant that you're losing performance with simpler apps. You don't necessarily even notice it.
I think I found with our app, it was once we switched to Flutter web that these performance issues kind of sort of raised in their head because they became much clearer where the performance was more limited. But on mobile in particular, I find most Flutter apps really fast out of the box, no matter how they're built. Oh, for sure. Yeah. You really, you really got to screw up to, to, to get the performance on a mobile app. Yeah.
It's like, oh, wait, am I calling that loop in the build? Oh, crap. That's why this is... Like, okay, don't do that. And my process for a lot of widgets that they need... Like, I use a variable widget for the body, for instance, for the scaffold. And say that it's going to load data there. And so at this point, I don't even need a change notifier because...
I set it to the circular progress indicator. So that's going to be the body of the scaffold or a widget that contains that. And it loads up and says, hey, you see a spinner by default. And then in the init state, you call an asynchronous method. It says, hey, go get this data. And when this data comes back, if it's successful,
Then show the view with the data that we just got. And if it's not successful, show an error. And then set the state. And so, you know, you're only setting the state once in this whole scenario. And so, yeah, you know, you can get into trouble if you, for some reason, are broadcasting events left and right and setting state over and over and over. But I think at that point you need to look at, like,
what am I doing with my data? Like, why is my data changing so frequently? And boy, let me tell you, you can definitely do that with block too. Because this last app I worked on, we had to fix some of that. And so I think one of my problems with block is there's a lot of ways to really do it wrong. And I guess it's probably true of most state management. Like,
If you don't do it right, you can run into horrible performance issues with block just as easily.
That's an interesting point. I found that very much when I was first learning design patterns. I got so excited every time I learned a new design pattern. I was kind of always itching to use it and apply it. And I found if I just wrote simple code, it usually worked pretty well. If I tried to apply the wrong pattern, it would just be a world of hurt. It would just be a horrible, horrible code. Obviously, if you find the right pattern that fits, that's the best case. But when you choose wrong and then go for it, it can be very difficult. Because again, you can be over-engineering in the wrong direction of what the app really needs.
Yeah. Isn't ideal. I'm curious what you use for your backend and how do you communicate front end to backend? Oh, wow. Still PHP MySQL running on a Apache server. And I'm actually using WP Engine. That's WordPress. It's WordPress optimized. Like that's pretty much all they do. And I use that for runp.com. And then I've got runp.net.
is for the, the, the API for the app. So in the future, so that was like one of my dumbest things that I've ever done. Like, I just want to go back to my previous 2018 self. And it's like, don't put the API on the same domain as the blog, you know? So when CNN published the,
Um, and all these about run P and all these people came to run P.com. It just overwhelmed. And, you know, WordPress is pretty heavy lift. Um, it is overwhelmed the server and, you know, that took out the, uh,
the app API as well, which couldn't get a connection through. And the RunP API for the app is really, really minimal. It's sending just tiny, tiny bits of data. So it's running on its own server. It's happy by itself. And there's practically nothing that could go wrong with that.
That being said, this month, well, next month, I'm building an app and I'm going to build it with Firebase and AWS and maybe a few different because I've just never needed to use other backends.
And I kind of feel like people are talking about all these other options, GraphQL. And it's like, okay, you know, I should build some sample apps and like know what they do well and what they do poorly. Because right now I've got like one tool in my toolbox that is PHP and MySQL and it works, but there might be better solutions. So I'm going to spend a month just kind of tinkering with different back ends for the same project and see, you know, what works best for everyone.
different things. - Cool, good luck. I'm curious to know how it works out. - What's your favorite backend? - I actually also use MySQL and PHP. Who's Laravel? Are you familiar with Laravel framework? - I don't use a framework on the backend. I just-- - It's a PHP framework for PHP. It's very similar to Ruby on Rails. It's kind of like Ruby on Rails for PHP. And then we create a very simple REST API and it works. The benefits, cons, pros and cons. It's very fast.
It's very cheap. These are both very good. The downside, I would say, is it requires a fair amount of maintenance and just people who can maintain it. I'm lucky to have a partner who's an expert in that field and helps with it. But if I was just working by myself on an app, I would most likely use something like Firebase, just because of the peace of mind. You have a back end that's always up, always running, doesn't need updates. Exactly. I would say one of my biggest takeaways in developing the RenP app is...
versioning the backend. So with every version, with every update of the run P app, it gets its own API and it may be identical to the previous one, but like I, you know, there's a path on the server to it. And, you know, I've got like 6.1 or 6.0, 6.1, 6.2, 6.3. So anytime I do want to change the API, I could go in there and wipe it out and refactor the entire thing. And I don't have to worry about,
about messing up people who haven't updated the app yet. I'm working on a client project that's been out there and they didn't version the API and it has been no end of headache. It's like, well, we can't really do that because that'll screw these people up. And I'm like, well, how do we fix anything? Anything else you'd like to add? Oh gosh. Yeah.
I'm really excited about Flutter. Hopefully COVID is drifting away. I'd love to get to some Flutter conferences and meet some other Flutter people. I think that is one of the things that I really miss about Flex. I'm still really good friends with a lot of my old Flex buddies and gals from Flutter.
you know, back in the, I think, actually the 360 Flex conference that started in
Uh, 2008. No, no. Before that, it's like everybody that went to that conference signed up for Twitter at the same time. So like nobody had ever heard of Twitter and we all signed up for it. And like, we've all, you know, kept in touch and we had like a big family reunion thing during the pandemic. And, you know, I would love to get that back with the Flutter community. And I think there's a lot of potential there that, um,
it seems already to be larger than the flex community was. Um, but I just haven't seen like any nice conferences, you know, sprouting up for this yet, you know, just a few here and there, but I'm really looking forward to getting to a good conference out there and meeting some other developers and, you know, just sharing our stories and hanging out and complaining about, uh, clients. Yeah.
Excellent. I hope to get a chance to meet you at a conference one day. I know Flutter Vikings is here and it's in Europe and I'm sure there'll be more conferences in America also. I know. Yeah, it'll happen. It'll happen. Yeah. Amazing. So Dan, thank you so much for coming on the podcast. I really appreciate it. It's a really interesting story. Sounds like an amazing app. I'm definitely going to download it now that I know it has the end credit feature. That's a, that's a seller for me. I could use that for each movie I see. Awesome. Awesome. Really happy to hear that. And thank you again for having me on. Um,
Yeah, I'm really looking forward to growing with the Flutter community. Awesome. So thank you again, and thank you everyone for listening. Until next time.