Leave the backend to us: mobile apps with Windows Azure Mobile Services
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Georgiev, Yavor
Azure Mobile Services lets you provision a cloud backend for your mobile apps without the need for server code, while you focus on what’s important: your app’s user experience. Use any client platform, including iOS, Android, and PhoneGap. Easily configure authentication for your app users with their Facebook, Twitter, Google, or Microsoft Account credential. With a few lines of code, send push notifications or run scheduled jobs on the server. In this talkwe will dive deeply into these areas and implement a rich app ready to submit to the app store.
 Hello, can you guys hear me? Yeah. It's 5.40, so time to get started. Thank you for coming to my talk. My name is Yavor. I work at Microsoft in the Windows Azure group. I work on a product called Windows Azure Mobile Services, which is a very easy solution for you to build Cloud-connected mobile applications. So in the next hour, we're going to spend about 20 minutes introducing what mobile services is, and most of the talk just going through our key scenarios doing a bunch of coding demos. So I hope that's what you're here to basically learn how to write an app with mobile services. I know it's the last session of the day, so I'm a little bit tired. I was a little bit sleepy going up the stairs here until I realized my podium is actually floating over the edge here a little bit. So I woke up pretty quickly after that. All right. So how many of you have used mobile services before? Let's see a show of hands. Okay. It's very bright in here. Maybe five people. How many of you have actually built an app and finished it with mobile services? Okay. So two experts we got here and everybody else pretty new. That's pretty good. So yeah. Pretty much covered with the agenda. What we're going to cover, we're going to spend a little bit of time at the end talking about kind of future things that are coming up with mobile services, what's in plan for the next six months or so, and then leave a little bit of time for Q&A at the end. So I already talked about this, but what is mobile services? Why are we all here? Well, we know there's a lot of developers out there that want to write apps for mobile devices, Windows Phone, Windows 8, iOS, Android, but they don't know how to write server code. So the goal of our product is to enable them to easily write these connected apps without the need for server code. If you'd like to write server code, if you're a server developer, you can by all means come and use our product as well. But kind of our key message is you don't have to. We provision the back end for you, so you don't have to worry. So before I go into this, let me actually show you what kind of apps we're talking about here. So let's say I'm a little hobbyist developer and I want to write a little game. So I have this Connect 4 game. So I connect four dots in a row and I win. And I want to put it in the store and I want to make it social. I want people to be able to play with each other. So let's go and see what I came up with. Here's my little very primitive UI. And I have kind of on the left side, you'll see the open games. So these are games that are waiting for players. And then on the right side, you see the games I'm participating in. So this is kind of my simple game that I built here. And then I can create a new game. So I press Start New Game down here. And I'll open a new game. So here you go, game 14. And the first thing you notice, it actually knows who I am. I didn't have to sign into this app. So that's one of the things that mobile services does for you. It takes care of authentication. So I threw a single sign on the app and you already who I was without me having to type in my credentials. OK, great. So I created a new game. What if I want to join an existing game? Let's say I want to join game 10 here. And I have a little loophole in my code that lets me play with myself. So I can actually demo this without inviting somebody else on stage. So there you go. Here's my game. And then I can go ahead and try and make a move. OK, and what just happened? I actually, up here in the corner, you didn't hear it, but it popped up. It's a push notification. So because I'm both the red player and the yellow player, it's like, oh, well, it's your turn. So OK, I make another move. And I'll get another push notification. So as a player needs to do something, he gets a push from the server. OK, so that's great. I have a Windows 8 app. But I want to maximize my revenue. I want to go and use the Windows Phone Store as well. I want to go in the iTunes Store as well. So let's go to more platforms. I don't want to just do Win 8. So if I head here to my emulator, I actually have Windows Phone 8 brought up. I have, using the same mobile back end in the cloud, I've built a Phone 8 version. And Phone 8 is a little bit different from Win 8. Authentication works a little bit differently. So I have to actually log in this time. But I'm using my Microsoft account. So I didn't have to create a different set of credentials or anything like that. And I can't hide my password, so I have to type it kind of in the corner here. If somebody knows a trick about how to do that, let me know. All right, so I'm logged into my app now. I have to authorize it. I get the same familiar view of the open games and the games that I'm participating in. And you'll notice it's the same server data. It's the same list of games I had before. I go into my game number nine or 10, whichever one I was playing here. And so it's pretty much the same UI. I can go and make a move again. And I have the Windows 8 version installed, so I still get my push notification, no matter which device I'm playing on. If I'm playing on a Win 8, I get it on the phone. If I'm playing on the phone, I get it on Win 8. So let's try it the other way around. So I'll make another move here. I'll go back to my Win 8 app. I'll make a move here. And then if I go back to the phone now, actually, I need to minimize the app so I get my toast notification. So if I go back, make another move in Win 8, and then go back to my phone here, you'll notice I got a phone notification as well. So it does the right thing. It notifies all the devices where I'm playing the game. It knows who I am, sends the push notifications correctly. So that's the value proposition of mobile services. It does things like auth, push, and data. Really super easy. OK, so it's just kind of another way of saying that. We have these kind of vertical pillars, identity, messaging, notifications. We provide kind of a common single management experience. So you go to the Azure portal, you go in one place, and you manage all these things for your mobile application. And we provide a single API, a single consistent API that you can code against to access all these capabilities. That's really what mobile services provides for you. Our mantra for mobile services is really simplicity with enablement. And what we mean by that is simple things should be really simple. Getting the three things I mentioned, push, auth, data, getting those things started should take you five minutes, or 10 minutes, but no more than that. Then if you become an advanced developer at that point, or if you already are an advanced developer, if you already have been writing server code for the longest time, you shouldn't be trapped. You should be able to extend it. So that's why we say simplicity with enablement. We leave a lot of extensibility points open for you. So you can go ahead and build on top of what we offer. I like to put these Legos up here. You can be the guy on the left who wants to just follow the directions, and he knows that in five minutes he'll end up with this exact product that he's aiming for. So it's very productive, very predictable. We want to do that. We also want to cater to the guy who wants to kind of tinker and add things. So we try not to be one or the other. We try to kind of let you do both. We're a pretty new service in Azure. We've actually been around in the portal for maybe only around a year now, or even less than a year. But we're a very feature rich platform. So some of the features we have are listed here. Some are in the pipeline, and even not listed yet. But we support a pretty full set of clients at this point. Windows 8, Windows Phone 8, Windows Phone 7.5 we added recently, Android, iOS. We have this HTML client, so you can actually use a website and this JavaScript to talk to your mobile back end as well. Or a PhoneGap application. So that's kind of an interesting cross-platform scenario where you guys are familiar with PhoneGap, most of you? It's a solution that lets you write your application in JavaScript and then publish it as iOS, Android, and all the different stores. So kind of a way to do it once and get in all the different stores. So you can do that with our HTML client. So yeah, pretty good support across the board for the different clients. We even support actually ASP.net. So if you want to have your server back end talking to your mobile back end for some reason, I mean there's some people that like to do that. We even support that for you. We support authentication with the four big auth providers today. Microsoft Account, Facebook, Twitter, and Google. We support push notifications. You had a question? Yeah, do you support connecting the different authentication providers to the server account? No, so that's a feature that we don't have yet, which is the question was can I connect my different identities from the different providers into a single identity? We don't support that yet, but it's something we've thought about as coming probably in the next six months to a year. So push notifications, I already demonstrated. Scheduled tasks is one thing we added just about six months ago where if you want to have a cron job running or a scheduled task inside your mobile service to send periodic notifications out to all your customers, you can do that. The next point is actually a really important one, which is our ability to write actually server side logic. It doesn't have to be simple, like I said. And we support the server side programming model where you can write business logic. You can write validation rules and things like that. And it's all Node.js, so you can use the entire Node package manager system to bring in extra functionality into your back end. It's actually quite rich and quite extensible. The next point is a custom API, so that's kind of more rich HTTP APIs. That's a brand new thing that actually came out just today. You guys are the first ones to hear about this feature. Scott Guthrie hasn't even blogged about it yet, but he said I could talk about it to you guys. The next one is also brand new. So we support source control. So you can now edit your scripts either in the browser or via Git, publish them via Git to the cloud. And then we have great extensibility. We integrate with Pusher and SendGrid. So if you want to use third party services with your mobile service, you can do that as well. So pretty packed service. We do a lot. And for services still in preview in Windows Azure, I feel that's great. It's a really useful little thing. We also focus a lot on great developer resources. So we have our developer center, which gives you tutorials in all the different clients. So you get to pick. I'm running an Android app, and then we have an Android version of every tutorial. So that's pretty great. The other thing is GitHub. We keep almost all of our source code on GitHub. And it's open. We develop on GitHub, actually. So it's not like we hide away, and then we publish the GitHub once every six months. Our bugs are actually in the issue tracker. And you'll see our developers making commits into this thing daily. So we try to be very open. And we actually even take contributions back. So if there's a bug that we're sitting on and not fixing, and it's really blocking you, you can actually go ahead, open a pull request. Me or one of the other PMs on the team, probably Paul, we're going to review it, get back to you, and merge it into the product. And it's going to ship within the next couple of weeks. And you have your bug fix in the Microsoft products. That's pretty great. And because NDC is such a special conference, I'm giving you all 10 mobile services for free, each one of you. I'm getting blank stares. They're always free. 10 are always free. It's not really. Sorry. But there is another thing, actually. I'm giving you all free car. It's actually kind of true. So if you have an MSDN subscription with Azure, and you have an MSDN subscription, and you haven't activated your Azure, whatever it is, credit as part of the MSDN subscription, they're actually running a promotion right now. And as a chance you'll win an Aston Martin if you go to this URL. So if you haven't activated Azure on your subscription, there's never a better time than now to get your Aston Martin. That's actually a real thing, not a joke. All right, so enough talking. Let's jump into the code here and see how we build one of these things. So the first thing I'm going to do is head over to the Azure portal, which is where all good things start. So I go to the Mobile Services tab here on the left. It's this little icon that looks like a phone with a little sugar cube inside of it. And here's all my apps that I've listed. So I created just a few minutes ago this testing app. It's completely empty. It doesn't have anything. But I just want to give you an idea of the experience of starting out with mobile services. So it's a blank app. All I did is say Create. And then I see here the choice of the different client platforms. So I get to decide how I want to get started with mobile services, which platform I'm going to use. Let's say I'm trying to write an Android application. So I'll click on Android. And we have this kind of contextual getting started experience here with three easy steps. The first step is it tells me go ahead and install the Android developer tools, because you need that to write Android apps. Then I can create a table to store my data. So it's just I click this button, and it's going to do this to do items. So it's going to be like a to-do list application. And it says I already created it. If it wasn't there, it would have created it for me. And then I can download a pre-populated, pre-configured Android application that I can get started with. So I can go hit Download, and it'll just bring this zip file down. It's about a megabyte. Very easy. I've already done that. And because my emulator is super slow, I went into Eclipse. I imported my app here with our mobile library here. Mobile Services Library. And then I started up in the emulator. And this is what you're going to get right out of the box without doing any work, is this cloud connected app. And so I can go and add something here. Let's say give my talk. Add an item to the list. And then I can go and also mark something completed. It's always risky doing on stage, because these emulators have very particular networking requirements. And sometimes it'll drop off without knowing why. So I'm making changes to my server data. And if I just head back to the portal here and click on this data tab, I see the to-do item table I just created. And I can actually browse all my items in real time, the ones that are stored in my cloud back-end. So here's the give my talk item I just created. I can check in real time whether it made it. So there you go, in just literally five minutes. And you can have an app that you can take to your boss and be like, look, we have an Android expense app now. Finally, it's done. Just change the title from to-do list to expenses. And you're all expense approval and you're done. So great. So that's how you do the very basic thing, create a table. Let's look at some of the other tabs here. Actually, while I'm in the table itself with my data here, there's this script tab. And I talked about the server scripts that you can write. So I can go ahead here and actually write a script for all the four code operations against my data. So if I want to validate that you're not allowed to do list with swear words in it, or you're not allowed to submit an expense for more than $1,000, I just write a simple node script here. Some of the other tabs, the scheduler, is where I do the scheduled jobs that I mentioned. Push and Identity is where I configure my push and identity and authentication settings and things like that. Logs is if my app generates logs in the server, we want to make it very easy for you guys to see those logs. You don't have to go remote into the VM and poke around some folder somewhere. We just bring them right here to the portal. So that's kind of a very quick lap around mobile services and the basic things it does. Any questions before I dive into my game and show you how that was built? Question right there? I'm sorry, I couldn't hear you. Support for node on server scripts and for what exactly? No, so currently our server, the question is do we support anything else but node in our server scripting model? Currently we only support node in our server scripts, but it's definitely one of the top two or three things that people ask for, especially if you're a.NET developer. You're writing your Windows 8 app in.NET. You want to write your server in.NET as well. So that's something we're definitely looking at. It's a little bit tricky though because we don't want to scare away people that want to write Android apps and iOS apps. We picked node because it's kind of a neutral thing that everybody's fine with. If we made it.NET, we would have scared away a lot of people. So we want to ideally have a choice for you and let you pick which one. Great, so let's go into my little app. So here's, I've already pre-created it. It's called Align 5. Here's my errors from before. But the first thing we want to look at is kind of my data tab here. And so my app, my game is powered by these two tables, my games and then my players. So when somebody first opens my game and they type in their credentials, I create a little player record for them in this players table. And the games table just contains a record of all the ongoing games. So pretty easy. Let's jump into Visual Studio here. So I think I have the phone one and the Win 8 one open side by side. This is the Win 8 one. So the first thing I needed to do is in my Win 8 app, I need to add a reference to the mobile services SDK. So we're actually up on NuGet. So if you go to manage NuGet packages, you can see the package I referenced, basically, which is windowsazure.mobileServices. That's our package. And we've tried to be, remember going back to that simplicity with enablement thing. We don't want to really tie your hands and implement everything in a little closed box that you can't look inside. So we've taken advantage of a lot of the community packages that are out there. Instead of using our own serialization, we use json.net. Instead of writing our own HTTP client, we use the HTTP client that ships with the framework. We support portable class libraries, which is a great way to make the same code actually run across a bunch of different C-sharp platforms. This is why you can easily write ASP.net code as well using RSDK, because we use portable libraries. So that's great. This is pretty new. It's been only out there for a month or two, our NuGet package. So that's the first step. By out of the NuGet package. And then I need to configure my connection information. So if I go back to the Quick Start here and say I'm using Windows Store, I need to have the URL in the application key so that my application can talk to the mobile service. So it's just right in here. And I've pasted it inside my VS instance. I've put it in kind of a little config file somewhere, because I didn't want to accidentally check it into source control or anything. So I put it in a little separate file here. And then I created an instance of mobile service client, which is kind of your entry point into using mobile services. I just created it here and pulled in the URI and the application key. So I have my instance here. Now I can use it from anywhere inside the app. So the first thing I'm going to do is in that page where I list the games. Let's find that. Main page. I create references to these two tables that I showed you, the game table and the player table. And I use the mobile service client that I put in my app static class. And then I have these two local objects, the game object and the player object. So if I go to the game object, you'll notice they're just polkos, plain old C-sharp objects. Nothing special here. I've added some JSON.net serialization attributes, because I prefer to lowercase my properties, but that's really a personal preference. You don't need to add these attributes. It's pretty simple classes, right? Just game and the names of the players and things like that. So that's pretty easy. But the one thing that I want to draw your attention to is in the portal. I didn't ask me anywhere when I create these tables, my games and my players. This is how I create a new table if I wanted to. It doesn't ask me anywhere, OK, what columns do you want? What schema do you want for your table? And that's one of the cool things that Mobile Services does for you is it will actually look at the object that's coming in on the wire, the JSON. It will just try to infer what database columns it needs to create. So actually, we call it auto schema or default schema. It will just infer based on what's coming in and pre-populate your table for you, which is a huge time saver if you're quickly prototyping an app. Then when you go to production, you want to turn that off, because you don't want just some random person with Fiddler going in and adding a bunch of new database columns. So you want to turn off that feature in some of the configure tab. Or maybe on the enable dynamic schema. So you just go ahead and turn that off when you're done with your development. OK, so we went through. And then let's see the actual, so how do we actually insert into this table? Let's go down here. I'll skip a few of these. Let's go this refresh method. And that's the method that fires whenever somebody goes on that page, basically, after they've authenticated and done all that stuff. So I'm using link on the client, which is actually pretty sweet. So the open games are just games that player one is set to something, but player two is not set to something. So that's how you know it's an open game. And then my games are the games where I'm either player one or I'm player two. But it's a pretty ugly looking link query. Imagine how hard that would be if you had to write a SQL. I mean, it probably wouldn't be that hard if you're a SQL expert. But we try to make it super easy to do things like this. And this is link on the client, but actually gets serialized and run on your server. So it's not running client side. It's actually running server side. So it's easy, but also performs pretty well. So that's how you just load up a bunch of stuff. And then I call two list async. So I put my link query, and then I terminate it with something like that. So we can give you a list, or if you want, we also have two collection async. And we have two incremental loading collection. And these are a bunch of really nice convenience things we added. If you want to bind to that control and winnate, the infinite scrolling thing, you just use one of our collections that does it out of the box. You don't have to worry about implementing all the loading events and all that. We try to make that super easy. So we covered loading stuff into it. Let's look at updating something. So I go against my table, and there's an update async method, pass it the new updated table, very straightforward. Insert as well, very straightforward. Just insert async. I pass it a new object instance. In this case, a blank game. If they click New Game, I just create a new blank game and insert it. So that's kind of the basics of the data model on the client. Now let's look at the way we do scripts on the server. So if I go back to, let's say, the games table here, and then I go to the scripts. Let's look at the scripts I actually have. So here's the insert script, which happens when someone tries to create a new game. Let's go kind of piece by piece. So you'll notice it's kind of a set shape. It has to be called insert, the little function. It has to have these three parameters. First parameter is the thing that they pass me on the wire, deserialized. The second thing is the user object, which is something as part of our authentication model, which I'll talk about later. And request is a handle to the incoming and outgoing HTTP request, so you can read things like headers, and you can go and write stuff out to the response directly if you'd like. Then I start modifying the object that came in in my script. So I'm not going to trust their own ID. Like if they want to pretend to be a different user, so I'll use kind of our authentication to get the right ID. I'm not going to trust the one they configured. I put the state here, which is where I store the actual grid and where each move has happened. Who the active player is. I remove some properties. Then I call request.execute, which is how I tell mobile services, OK, I'm done with this object. Go ahead and process your pipeline going forward and insert it in the database. If I want to run some code after the insert completes into the database, I can add a little callback here and I'll fire after the complete is done. So insert is pretty straightforward. If I go into update, update is kind of the biggest method here. It's kind of huge. My entire game loop is inside this update method. It's a little bit cheating, but let's see what it does. So when they send me an update with a new instance of the game object, I'm not going to trust the game object they sent me, so I'll use this local reference to game table to pull it from the database. So if I want to access another table from inside these scripts, I use kind of this tables global. And I say get table. That's kind of how I get a reference to the table on the server. So I get my own instance. And here's a little query syntax. I say where, and then I can pass an object here, and it'll just do an equality comparison. So I'll say, OK, the item they tried to insert, give me the real one. I don't want to trust the one they gave me. And then when it completes, you call the read method to run the query. And then when it asynchronously completes this success callback will fire. Results will be in this property, obviously. And then I can check here, for example, if there aren't any results. So they're trying to update a game that doesn't exist. I'm just going to go ahead with a request object and just return a 404 right away. So this is a good example of say, OK, I want to break out of the pipeline. I want to say, I'm done processing this. Let's just move on and return a 404. Like there's something wrong with this request. So that's how I abort the pipeline. And if there is actually any results, I say, OK, the game is the first result, because obviously the ID is the primary key, so it has to be the first one. And then depending on what they're doing, whether it's the first time they try to become the second player, I say, OK, they're trying to join the game. Or if there's already a second player, they're trying to probably make a move. It's a little bit silly, my game logic. That's not why you're here to look at my crappy JavaScript. But you kind of get a sense of how you write these server scripts. And they're not as scary as you might think. And we have great documentation in our developer center where you can go and kind of see with the learn a little bit more about the syntax. So we've covered kind of the data stuff. Let me see if there's anything else. I think that's pretty much all I had when it comes to data. Do you guys have any questions so far about how to handle data? Probably somebody's going to ask me, can I use table storage instead of SQL? Because this actually uses SQL server in the back end. The answer is not right now. We're looking into it. That's another very common question. Yep, over there. I'm sorry? I can just video it back end. Right. So the question is, can I just use my own back end instead of the database that we generate for you? That's a really good question. And that's really useful if you already have an existing back end. Say you have an on-premise application. Now someone's telling you, I want a cloud version of that. Or actually, no, they're telling you, I want a mobile version of that. So how do you do it? We currently don't support it kind of in a first class way. If your SQL server schema for your table is kind of in a very expected format, it will work. We give you a way to specify a connection string to a different database. But you have to follow our own convention about what your tables are called and all of that. In the future, definitely. Kind of one of the big things in the next six to 12 months for us is kind of enabling these hybrid enterprise scenarios, so either using your own database. Or what's also interesting is from within your server script, using something like a service bus relay to just talk into your enterprise to an existing data store that you don't want to host up in Azure. So the expense app is actually a good example. You don't want to host the expense data up in Azure. You don't want to copy it. You just want to kind of open just one pipe just to that server from the cloud. And you don't want anybody else to have access to that. So that's definitely something that's not there today. But we're looking at that. Question? Can you access the SQL Azure from another server? Yeah, so the SQL server I'll show you, actually. We don't swallow it. Like we don't hide it from you. So if you go back to the portal, if I go up here to my configure, I think, you'll see it tells you, OK, it's the SQL database on this SQL server. So I can just click this arrow and actually take me to the SQL tab in the portal. And I can go and open the SQL management studio and go and look at it myself. So you can back it up and do all those things. So we covered data. That's kind of the first thing we always talk about. And then let's talk about auth. And this is where a lot of people fall asleep a little bit, so tell me if you're super bored. So the main, I'm going to go into the slide, the main goal with auth is to authenticate the app user in the app itself. So you can kind of customize it, show their little smiley face in the corner and put their name, hello, so and so. But also what's more important, actually, more interesting is to authenticate them on the server. So we can have their identity on the server. And then based on that, we can do authorization. And we can create some kind of rules on the server and things like that. So at the end of these authentication flows, we want to have their identity both on the client and the server. So our first authentication flow is what we call server auth. And this is kind of an OAuth 2-based flow using a little browser widget that we invoke. So when you call a login API on mobile service client, and it'll kind of open a little browser, and they'll type in their credentials, you saw me do that in the phone app. So that's kind of the server flow. And it's super simple. It's just one line of code. The developer types their credentials directly into the kind of the website, like a live ID or Facebook. And then the auth provider, still using the browser, will kind of redirect this authentication token back to the mobile service back end. So that's how we get the identity. And then mobile service will pass back to you some parts of that identity. So now you know who the person is, their user ID. So this is kind of the simplest way to do authentication. It uses this little browser control. You don't need an SDK from the auth provider. You don't need to figure out live connect or any of those things. This is very easy, but a little bit limited. Because mobile services is the one who manages the authentication token. So if you want to add extra permissions to it, you want to say, I want access to their basic information and their pictures maybe also. You can't really do that, because we manage the token for you. So if you want to do graph access against Facebook or Twitter, it's kind of limited what you can get using this flow. But it is very quick. That's kind of why it's the first one we talk about. We also have a client flow that relies on kind of a device specific, provider specific SDK. So a good example of that is on Windows 8, if I use the live connect SDK, it actually does single sign on for me. So when you saw my Win8 app, I didn't have to type in anything. I'm logged in with my live ID. The app knows exactly who I am. But for that, I have to use a native SDK for live connect. The same for Google and Android, right? They'll do single sign on. The same for Twitter does that. But I know definitely, I think Facebook does it on iOS. Facebook has kind of a built in thing on iOS that can authenticate you. So if you want to take advantage of these capabilities, we enable you to do that. So you'll type in your credentials in whatever their SDK does. It may have some native prompt or I don't know what it does. At this point, mobile services is not involved. And it'll send you back a token. So now you know who the user is. And you requested that token. So you could say, well, I want permission to access their picture library, their friends, their social security number, their credit card. You can add all those claims to the token because you requested it. And then you give it to mobile services so we can also get the identity of the user. So this is kind of a little bit trickier because you need to understand how their auth SDK works. And it's quite a bit more code. But it's powerful because now that token, because you requested it, you can put all the things on it and have quite rich graph access both on the client and on the server. So depending on your needs, if you just want something quick and dirty, use a server flow with the iFrame and kind of passive OAuth. If you want single sign on or rich graph access, you'd probably use the client authentication. I know this is a little bit dense. So let me show you some code here. Here's the, I skipped over the authentication method before. I'll show it to you now. Authenticate, there it is. So in this live auth client, so that comes from this reference I added over here to the live SDK. So I had to pull in the live SDK for win8. So I use, and this is boilerplate code from their documentation. I had to use the live auth client. And I call login on their client. And then when their authentication flow is done, I call this login with Microsoft account. That's how I pass, and then, sorry, you can't see it very well here, I pass the authentication token that they gave me in the result. I pass that back to mobile services so I can authenticate on the server. I could take this token now on the client and continue using it against live to get even more stuff about that user. So that's how it looks on Windows 8. On Windows phone, it is very similar. It's just a few tiny differences, but largely the same SDK. So you can go here, find the authenticate method. You notice it's kind of the same shape, and I end up doing the same thing. Just pass mobile services authentication token now. So this is the client flow because I want that nice single sign on. Now, if I wanted to do the server flow, let me show you how really easy that is. So I'd say something like, you know, get a reference to my client here, and then I do client login. So notice I'm using a different overload of login. So I just call login async here. And it takes the authentication provider. So I'll say, you know, Facebook. And then I need to await this call because it's synchronous. And then by the time, because it's asynchronous, by the time it's done, now here the user will already be authenticated. This login async will take care of popping up the browser, doing all that dance, getting me back to identity. So at that point, if I go and say client, it's current user, I think. Now, this current user object will give me a bunch of information about the user, like their user ID. And that's kind of their identity at this point. So the moment the second line completes, I have all the off on the client. So you can see how it's much, much simpler. But you get a little bit less by doing it this way. Undo all this. I'm going to break my demo. So yeah, so I showed you the client flow and the server flow from within a.NET app. Now, the one thing that I didn't show you is this didn't just work like that for free. So there's a little bit of server configuration I need to do here in mobile services. So if I go inside my app here, I go to the Identity tab. You notice I've pasted these two values for the Microsoft account. So you know when you create an app with these off providers, they need to know who you are, who's trying to authenticate. So they ask you to go to their little portal and create like a manifestation of what you're doing. So you register there and they ask you who you are. And so they know when people are trying to log in, what are you logging into? And when people log into your app, they'll see a little screen saying, so and so I was trying to get your authentication token to talk to a bunch of our resources. And it says who you are. So to do this, I went to this LiveConnect developer center. And this is a little bit tricky. The UX is not great, but it's documented really well on our Dev Center. So I created an application here. And then the key things that it gave me are the client ID and the client secret. So these are the two things I went and then I go ahead and pasted the two of them into my window here. And just a minute on why this client secret is important. This is to prevent spoofing. So if mobile services receives a token, it needs to have a way to verify that that token was actually issued by the authentication provider, not just some other person sitting in the middle. So it's a shared secret model. So this client secret is known both to Live and to Mobile Services. And you don't ever want to put it in the client, even those called client secret. You never want to do that. It's a server thing that sits there. And so when Live sends that token, it signs it with the secret. And then when Mobile Services receives it, it knows to check that signature using this client secret. It's kind of like a symmetric key kind of thing. So that's how we make sure that we can actually trust that token. So when you get something past your user object, you know that's been verified because we've checked it against this client secret. So speaking of that, let's see what's the model in server script to do authorization. So say someone's authenticated, right? How do I tell Mobile Services, OK, only let authenticated people see my data? Don't let anybody else see my data. So if I go to my permissions column here on my games table, you'll notice I have kind of a drop down with a few choices. Everyone is hardly ever used. Anybody with an application key is the default. So that's pretty much, you should consider that to be equivalent to everyone. Because the application key is not really secret. That's something that's bundled into your app in the store. And somebody can download it, reverse engineer it. So you don't want to consider this really like any sort of authorization mechanism. What you really want to do is say only authenticated users. And then you know that people have gone through that authentication flow. And they've presented a valid token that's signed with a correct secret. So this is how I can protect different operations on my table and say, OK, only authenticated people can go ahead and access these. This is very coarse. Like this is only on the operation level. So within an operation, let's see how I can make some more kind of fine-grained decisions. So if I go back to that insert script, somewhere down here, I have a piece of code. So this little thing here. So I have a record of whose turn it is in the game. And you don't want to be able to tell me, OK, well, actually it's my turn. And it's my turn again. So you kind of play yourself all the time. You want to actually protect the other player's turn. So they can try and tell me, OK, I am the active player. But we don't trust that. We actually go and say, OK, user.userID. So we get the ID from the authentication flow to make sure they're not pretending to be the other user. So that's an example where we do this. That's kind of usually how you do this. Also, you'll notice in the players table, I actually keep a record of this user ID. So this is how if somebody logs in, this is how I know they're kind of the same person. When they log in, I always get the same user ID. And so I can associate all their push settings and their name and all that. So that's kind of how I keep a record of them using that user ID. And I only get the user ID if I can figure the off flow. So that's pretty much it for off. Is there any questions? I know it's a little bit quick, but it's a little bit boring also. See a question back there. You're going to have to speak really loud, because I can't hear you at all. I don't have the Android version of this particular app, but I can show you of the login. Yeah, absolutely. That's actually a really good point. So the question is, how does this look in Android? And we've tried to maintain symmetry across all of our SDK. So ideally, if you can write it in.NET, you should be able to write it in Android. So I haven't done this before, but I will go over to our Dev Center and get the answer for you. So if you go in here, we have our authentication tutorial. So you say, get started with authentication. And I'm going to pick Android here, right at the top. And then I'll scroll down here. So there's a little bit of setup and stuff like that. I'll actually find the piece of code where you call login. So there it is, right? So client is the client instance that I created of my mobile services client. I call login. I have the same choice of authentication provider. And then async code looks a little bit different in Android. They don't have a wait, but they have this callback style programming. So this callback fires asynchronously when the thing completes. And then on completed, I get a reference to the user. So code looks very similar if you exclude the platform specific things. So I love our Dev Center. It's great. And we have a cheat sheet for all different clients. And you can go and if you want to see how you do this in iOS, which is all going to look like spaghetti to me if I try to actually understand it. But somewhere here, there will be something that looks like a login. Maybe it's this one. I guess? I mean, really? That's it, I think. It's true. OK, great. So we're done with authentication. Let's move on to the kind of the fun part, the push notifications. You had a question? How about your own authentication mechanism, like KD? Yeah, so that's a great question. The question is, can you have your own authentication mechanism? The short answer is currently we don't give you one out of the box. Currently, there's kind of my fellow PM Josh Twist. He has a blog post where he talks about how to do custom authentication. It's kind of going back to this enablement thing. It's very, it's a little bit manual, but you can do it. Going forward, we're definitely considering like a first class thing where you're going to go and federate with Active Directory, make it super easy, kind of the simplicity part. Currently, we're kind of the enablement part when it comes to custom auth. And then we want to get back to the simple thing to enable that as well. Currently, no, though. Currently, almost. Yeah, I don't think if, I don't know if anybody has done it with Active Directory. People have done kind of custom auth like where you have your own table, where you manage username's passwords with the right hashing and all of that. I don't know for sure that anybody has done Active Directory. So maybe you'll be the first. And you'll send me an email after. And then I'll talk about it. And people will think I'm smart. So how does push notifications work? So you're probably familiar that all the different phone vendors have their own push notification service. So Microsoft has two, actually, because we're extra special. We have WNS for Windows 8, and we have MPNS for phone 8. So that's how you push to those devices. Apple has APNS or APN. GCM is for Google. And the regular flow, the way you would do this is, imagine you don't even have mobile services in the pictures. The first thing is the device through some magic out of band way registers for a push channel. So I don't know how they do it. Is it HTTP, or is it something like in the network, in the cellular network? I don't know how it does it. But it basically checks in with the authentication service and says, OK, here I am. I'm ready to receive push notifications about something. And what it gets in return is this channel, which is kind of its address. So if somebody wants to send a push notifications, it can go back to the notification service with that channel and say, send this guy something. So the way we normally do this is, so then the device registers for channel, then sends it back to mobile services. And mobile services will stash it away in a table somewhere for later use. Probably will stash it with a person's user ID. So then we can later say, OK, this person needs a push notification. So you look up their channel, and you go ahead and you send them a notification directly with the notification service. This is great. It's very simple. But you can see how this will quickly start to fall apart if you are talking about really massive scale here. So the one problem with this is if you have a million users of your app, and you want to send a single push notifications to all million users, how many calls are you going to be making for mobile services? A million, right? You'll be making a call for every single notification you want to send. So this is great for small scale. And if you don't have these large blasts of notifications where everybody has to get the same one, if it's always the custom notification that's always very specific to just one person, then you're not really wasting much. But if you're broadcasting the same thing to a lot of people, this gets really tedious. So for that, we have this integration with another Azure feature called notification hubs. How many of you have heard about notification hubs? Very few. So it's this extra service that takes away some of this channel management and pushing for you. It's kind of this separate little infrastructure piece that takes that away. So the flow starts the same way. So you'll register your channel with the push service. Then instead of giving it to mobile services, and then you use the developer and mobile services, you have to now create a table and manage it, you give it to notification hubs, and you label it with a tag. So you say, my funky app, or people that should get notifications about app update or something. You create a descriptive tag that describes a group of people that you want to add this to. And then all mobile service has to do is send a single call to that tag saying, OK, everybody who's listening for app updates, I have my new version, I have a bug. You just send one notification to the tag. And notification hubs is responsible for delivering the million notifications through the respective notification service to the million devices that have registered for that tag. So it's kind of a mechanism to deliver push at scale. So notification hubs will do the heavy lifting for you, so then you don't have to do it in your mobile service script. Let's go ahead and do a quick demo, because I only have 12 minutes left. So let's go inside my Windows 8 app here. How many of you have done push notifications with Windows 8 so I can maybe skip over? OK, not very few. OK, a lot. So let's go to this check registration method. So this stuff here is kind of standard Windows 8 stuff. So you say, OK, this is kind of the black magic where the Windows 8 app talks to the notification service and registers. I don't know what happens in this call, but all I know is I get a channel back. And that's a URI that we can now use to address the phone. And then I actually stuff it right inside my player object. So I have this WNS property. It's in the player table where I had all my registered players, and I just send it to the channel URI. So that's all I need to do on the server to capture the channel and send it to the back end. On the phone, it's exactly the same except the property is called MPNS channel. OK, now the interesting part is how do I actually deliver the notification from my back end? So if I go here, I probably guessed that it's inside that giant update script in my game table, such as everything else. So somewhere down here, I have a function that I think right at the bottom. There it is. So this is a function to deliver a toast notification. So you'll notice I use this tables object again. I get my players table from within my game update. And then this is the power of this node model and this JavaScript server model. Like I'm actually talking to a different table now from the script for this table. It lets me combine things easily. So I get my players table here. I pull up the records for that user ID. Or there's actually going to be a unique record because user IDs are unique. And then I go ahead and I pull up the channel. So I say, OK, here's the WNS channel. It's just living in that property. The MPNS channel is living in that property. And then we have this very simple API. So we say push.wns, pass the channel, pass your message. And it's pretty much symmetric across the WNS and MPNS. And it's pretty much symmetric across APNS and GCM as well. It's very similar looking. So it's very easy to do it this way. I had to do one little piece of config here, which is again required for the push notification service and mobile service to establish a trust relationship. So for Windows, I had to paste these credentials from one of the portals. It's documented in our docs. MPNS actually doesn't require, it throttles you at 500 notifications per device per day. So they've said, OK, we don't care if you, we just got to throttle you. You don't need to authenticate. Apple actually uses a sockets-based connection to the notification service. So they actually ask you to upload a certificate to authenticate that you get from their portal. And Google has just an API key similar to WNS. So this is kind of where you configure the push, and that's just that one line in the script to send the notification. For notification hubs, I didn't have a demo prepared, because it's not fully baked in to mobile services yet. But I can show you kind of a slightly more advanced way to do it, which is, like I mentioned in Node, it's kind of an extensible thing. And it has similar to NPM. It has a package manager called NPM. And one of the packages on there is the Azure package, which actually my team ships as well. And the Azure package has support for a lot of these Azure services. So if you want to talk from your mobile service back end to blob storage or table storage, you'd use this Azure package. And so you can use notification hubs through the Azure package. So you just reference it. It's already in the box. You just have to say, require Azure to pull it into scope. And then you kind of create your notification hub reference. And then this is how basically you send to, if you just use this syntax, so WNS, send whatever, this whole thing here, you'll send it to all people that are subscribed to that hub. This first parameter, if you specify a string there or a comma-separated list of strings, then that's where you specify the tag, or set of tags you want to push to. If you pass null, it's everybody. If you pass a set of tags, you'll just push to those tags. So again, easy to do that a little bit more advanced, because you have to use an external module. It's not kind of in the box. But it's easy to reference it. OK. So let's kind of push at a glance. And with that, I'm kind of done with our coding demo. Any questions on push? We spent a little bit of time talking about the timeline and where we're headed with this. OK. So like I said, I think mobile service has been around for less than a year. First, we launched our preview with support for Windows 8. That was kind of the first thing we did. These core scenarios, the data often push. Then we quickly kind of added iOS support, Windows Phone 8 support after that. This was, I think, towards the end of last year. Then early this year, we added a schedule or in support for command line tooling. That's not even something I showed you. But instead of using the portal, you can do a lot of that stuff from command line tooling. It was very recently, about two, three months ago, we added HTML client, notification hubs, Android support. So you see it's kind of very incremental and we're building up on our capabilities. Today, literally today, about six hours ago, we lit up support for custom API and source control. So I'll just kind of show you in the portal where those are. And don't tweet about it until Scott blogs. And then you can all re-blog him. But this is where you do a custom API. A custom API is kind of like a powerful kind of HTTP only script. So for example, if you want to have a submit shopping cart kind of thing, where do you put that? Because that requires updating your list of widgets or whatever you're shipping. And it requires updating your customer table. It requires kind of touching multiple tables. It doesn't make sense really as an insert or update. You see I had that problem with my game script a little bit. My game update, I was putting everything inside the update. So if you have these kind of bigger pieces of script that kind of touch multiple tables, you can just create an HTTP, just the random HTTP API, like submit, order. And then you can configure different permissions for the different HTTP operations here. And you can just write your script in a very familiar way. The other thing that literally shipped today is support for source control. So a lot of you may have found it kind of frustrating to edit the scripts in the Azure portal. You don't have to anymore. You just go through the set up source control thing. And I'm not going to go through it. It's a very scary message, actually. It says, do you want to enable source control? This is a preview feature. We recommend that you back up your scripts regularly. So that's pretty intimidating. But if you press that button, you can use Git to push your scripts to your service after backing them up regularly. So these are kind of the two new things. And then there's kind of a bunch of question marks after that. What happens after this? So I can't tell you the order of these boxes, but I can tell you what's in some of them. One of the big ones that is on our mind is general availability for the service. You saw the preview tags everywhere, and kind of the preview language. We're looking to make mobile services generally available sometime this year. So you can kind of put the full backing of Azure with compliance and disaster recovery and all those things built right in so you can really trust us with your data. Another thing is kind of this set of enterprise scenarios that I already talked about, basically connecting to an existing data store, connecting to an on-premise data store. So that's another big direction. A third big direction is what we call brand applications. So we realize a lot of developers out there, a lot of studios and consultancies out there, really have this kind of same sort of requirement. They'll have a customer come and say, build this very cool app that really showcases kind of our brand. Might not be super feature rich, but we need something quickly out there for people to sign up for our fishing ships campaign. It needs to be catchy, but we need to get it done quickly. So we want to tailor for those scenarios as well. So kind of agencies and then enterprises, big directions going forward for mobile services. And that doesn't mean if you're just an indie developer doing a game with mobile services like I did, that doesn't mean that's not OK. You can still do that. We're still going to support you just the same. But that's kind of where the big new feature areas are going to be. Great. Already touched on this, but in your server scripts, if you want to use Pusher to send push notifications to web browsers, or you want to use SendGrid to send email, or use Twilio to send SMS, we have these partnerships through the Azure Store. So if I go ahead and go into the Azure Store here, I can go ahead and I already have a Pusher extension that I've added before, but I can go ahead and add a new extension here so I can pull in, let's say SendGrid if I want my server script to send some email, let's go find it in the list here. And we automatically configure the billing relationship with SendGrid. Of course, a lot of these are free to start. SendGrid is free for the first couple of thousand emails or something like that. But after that, you'll just get one bill from Microsoft. The SendGrid stuff is going to get added to the bill. You don't have to go and separately register. So that's kind of a neat thing. And last but not least, our customers. We've seen quite good adoption of mobile services, especially in Windows 8. It's hard to make the argument to Android and iOS developers to come and use a Microsoft product and use something with Windows in its name. It's a little bit of a hard sell for us. But as you've seen, the platform itself, there's nothing really Windows specific. All the APIs I showed you, they all work on Android and they all work on iOS. So there's nothing about mobile services, and we use Node on the back end. So there's nothing that traps you into the Microsoft ecosystem if you want to do an iOS app or an Android app. It's just been slightly tricky to get that message across. So please spread the word. One of our very exciting apps in the store is actually VGTV. And this is probably the one country where people know what VGTV is, right? There's no VGTV. Please tell me someone knows. OK, good, OK. All right, good. Yeah, so they're a TV channel and a website, I think, or a website that's trying to turn into a TV channel, or something like that. But they have a great app and they really use everything. They use data. They use push notifications. It's a great app. You can go and grab it in the store right now. So with that, go ahead and sign up. We have a short URL. If you go to windowsazure.com. You can sign up for our service. And with that, I'm pretty much out of time. Thank you very much for staying with us. Out of time, thank you very much for staying around for the last session. Please go ahead and give me any feedback. Send me an email if you loved it or you hated it. If you need more information, my Twitter and Facebook are on there. I can write my, sorry, my Twitter and blog are on there. I can write my email address for you if you have a question. But other than that, thank you very much. And we have unlimited time for questions since it's the last session. So you can be here all night. You don't have to go to the party. This is the parties right here.
 Hello, can you guys hear me?  Yeah. It's 5.40, so time to get started.  Thank you for coming to my talk.  My name is Yavor.  I work at Microsoft in the Windows Azure group.  I work on a product called Windows Azure Mobile Services,  which is a very easy solution for  you to build Cloud-connected mobile applications.  So in the next hour, we're going to spend  about 20 minutes introducing what mobile services is,  and most of the talk just going through  our key scenarios doing a bunch of coding demos.  So I hope that's what you're here to basically  learn how to write an app with mobile services.  I know it's the last session of the day,  so I'm a little bit tired.  I was a little bit sleepy going up the stairs here until I  realized my podium is actually  floating over the edge here a little bit.  So I woke up pretty quickly after that.  All right. So how many of you have used mobile services before?  Let's see a show of hands.  Okay. It's very bright in here.  Maybe five people.  How many of you have actually built an app and  finished it with mobile services?  Okay. So two experts we got here and everybody else pretty new.  That's pretty good. So yeah.  Pretty much covered with the agenda.  What we're going to cover,  we're going to spend a little bit of time at the end talking  about kind of future things that are coming up with mobile  services, what's in plan for the next six months or so,  and then leave a little bit of time for Q&A at the end.  So I already talked about this, but what is mobile services?  Why are we all here?  Well, we know there's a lot of developers out there that want  to write apps for mobile devices,  Windows Phone, Windows 8, iOS, Android,  but they don't know how to write server code.  So the goal of our product is to enable them to easily write  these connected apps without the need for server code.  If you'd like to write server code,  if you're a server developer, you can by all means come and use  our product as well.  But kind of our key message is you don't have to.  We provision the back end for you,  so you don't have to worry.  So before I go into this, let me actually show you what kind  of apps we're talking about here.  So let's say I'm a little hobbyist developer and I want to  write a little game. So I have this Connect 4 game.  So I connect four dots in a row and I win.  And I want to put it in the store and I want to make it  social.  I want people to be able to play with each other.  So let's go and see what I came up with.  Here's my little very primitive UI.  And I have kind of on the left side, you'll see the open  games.  So these are games that are waiting for players.  And then on the right side, you see the games I'm  participating in.  So this is kind of my simple game that I built here.  And then I can create a new game.  So I press Start New Game down here.  And I'll open a new game.  So here you go, game 14.  And the first thing you notice, it actually knows who I am.  I didn't have to sign into this app.  So that's one of the things that mobile services does for  you.  It takes care of authentication.  So I threw a single sign on the app and you already who I  was without me having to type in my credentials.  OK, great.  So I created a new game.  What if I want to join an existing game?  Let's say I want to join game 10 here.  And I have a little loophole in my code that lets me play  with myself.  So I can actually demo this without inviting somebody  else on stage.  So there you go.  Here's my game.  And then I can go ahead and try and make a move.  OK, and what just happened?  I actually, up here in the corner, you didn't hear it,  but it popped up.  It's a push notification.  So because I'm both the red player and the yellow player,  it's like, oh, well, it's your turn.  So OK, I make another move.  And I'll get another push notification.  So as a player needs to do something, he gets a push  from the server.  OK, so that's great.  I have a Windows 8 app.  But I want to maximize my revenue.  I want to go and use the Windows Phone Store as well.  I want to go in the iTunes Store as well.  So let's go to more platforms.  I don't want to just do Win 8.  So if I head here to my emulator, I actually have  Windows Phone 8 brought up.  I have, using the same mobile back end in the cloud, I've  built a Phone 8 version.  And Phone 8 is a little bit different from Win 8.  Authentication works a little bit differently.  So I have to actually log in this time.  But I'm using my Microsoft account.  So I didn't have to create a different set of credentials  or anything like that.  And I can't hide my password, so I have to type it kind of in  the corner here.  If somebody knows a trick about how to do that, let me know.  All right, so I'm logged into my app now.  I have to authorize it.  I get the same familiar view of the open games and the games  that I'm participating in.  And you'll notice it's the same server data.  It's the same list of games I had before.  I go into my game number nine or 10, whichever one I was  playing here.  And so it's pretty much the same UI.  I can go and make a move again.  And I have the Windows 8 version installed, so I still  get my push notification, no matter which device I'm playing  on.  If I'm playing on a Win 8, I get it on the phone.  If I'm playing on the phone, I get it on Win 8.  So let's try it the other way around.  So I'll make another move here.  I'll go back to my Win 8 app.  I'll make a move here.  And then if I go back to the phone now, actually, I need  to minimize the app so I get my toast notification.  So if I go back, make another move in Win 8, and then go  back to my phone here, you'll notice I got a phone  notification as well.  So it does the right thing.  It notifies all the devices where I'm playing the game.  It knows who I am, sends the push notifications correctly.  So that's the value proposition of mobile services.  It does things like auth, push, and data.  Really super easy.  OK, so it's just kind of another way of saying that.  We have these kind of vertical pillars, identity,  messaging, notifications.  We provide kind of a common single management experience.  So you go to the Azure portal, you go in one place, and you  manage all these things for your mobile application.  And we provide a single API, a single consistent API that you  can code against to access all these capabilities.  That's really what mobile services provides for you.  Our mantra for mobile services is really simplicity  with enablement.  And what we mean by that is simple things  should be really simple.  Getting the three things I mentioned, push, auth, data,  getting those things started should take you five minutes,  or 10 minutes, but no more than that.  Then if you become an advanced developer at that point, or  if you already are an advanced developer, if you already  have been writing server code for the longest time, you  shouldn't be trapped.  You should be able to extend it.  So that's why we say simplicity with enablement.  We leave a lot of extensibility points open for you.  So you can go ahead and build on top of what we offer.  I like to put these Legos up here.  You can be the guy on the left who wants to just follow the  directions, and he knows that in five minutes he'll end up  with this exact product that he's aiming for.  So it's very productive, very predictable.  We want to do that.  We also want to cater to the guy who wants to kind of  tinker and add things.  So we try not to be one or the other.  We try to kind of let you do both.  We're a pretty new service in Azure.  We've actually been around in the portal for maybe only  around a year now, or even less than a year.  But we're a very feature rich platform.  So some of the features we have are listed here.  Some are in the pipeline, and even not listed yet.  But we support a pretty full set of clients at this point.  Windows 8, Windows Phone 8, Windows Phone 7.5 we added  recently, Android, iOS.  We have this HTML client, so you can actually use a website  and this JavaScript to talk to your mobile  back end as well.  Or a PhoneGap application.  So that's kind of an interesting cross-platform  scenario where you guys are familiar with PhoneGap, most  of you?  It's a solution that lets you write your application in  JavaScript and then publish it as iOS, Android, and all the  different stores.  So kind of a way to do it once and get in all the different  stores.  So you can do that with our HTML client.  So yeah, pretty good support across the board for the  different clients.  We even support actually ASP.net.  So if you want to have your server back end talking to  your mobile back end for some reason, I mean there's some  people that like to do that.  We even support that for you.  We support authentication with the four big auth  providers today.  Microsoft Account, Facebook, Twitter, and Google.  We support push notifications.  You had a question?  Yeah, do you support connecting the different  authentication providers to the server account?  No, so that's a feature that we don't have yet, which is the  question was can I connect my different identities from the  different providers into a single identity?  We don't support that yet, but it's something we've thought  about as coming probably in the next six months to a year.  So push notifications, I already demonstrated.  Scheduled tasks is one thing we added just about six months  ago where if you want to have a cron job running or a  scheduled task inside your mobile service to send  periodic notifications out to all your customers, you can do  that.  The next point is actually a really important one, which  is our ability to write actually server side logic.  It doesn't have to be simple, like I said.  And we support the server side programming model where you can  write business logic.  You can write validation rules and things like that.  And it's all Node.js, so you can use the entire Node package  manager system to bring in extra functionality into your  back end.  It's actually quite rich and quite extensible.  The next point is a custom API, so that's kind of more  rich HTTP APIs.  That's a brand new thing that actually came out just today.  You guys are the first ones to hear about this feature.  Scott Guthrie hasn't even blogged about it yet, but he  said I could talk about it to you guys.  The next one is also brand new.  So we support source control.  So you can now edit your scripts either in the browser or  via Git, publish them via Git to the cloud.  And then we have great extensibility.  We integrate with Pusher and SendGrid.  So if you want to use third party services with your  mobile service, you can do that as well.  So pretty packed service.  We do a lot.  And for services still in preview in Windows Azure, I  feel that's great.  It's a really useful little thing.  We also focus a lot on great developer resources.  So we have our developer center, which gives you  tutorials in all the different clients.  So you get to pick.  I'm running an Android app, and then we have an Android  version of every tutorial.  So that's pretty great.  The other thing is GitHub.  We keep almost all of our source code on GitHub.  And it's open.  We develop on GitHub, actually.  So it's not like we hide away, and then we publish the  GitHub once every six months.  Our bugs are actually in the issue tracker.  And you'll see our developers making commits into this  thing daily.  So we try to be very open.  And we actually even take contributions back.  So if there's a bug that we're sitting on and not  fixing, and it's really blocking you, you can actually  go ahead, open a pull request.  Me or one of the other PMs on the team, probably Paul, we're  going to review it, get back to you, and merge it into the  product.  And it's going to ship within the next couple of weeks.  And you have your bug fix in the Microsoft products.  That's pretty great.  And because NDC is such a special conference, I'm  giving you all 10 mobile services for free, each one of  you.  I'm getting blank stares.  They're always free.  10 are always free.  It's not really.  Sorry.  But there is another thing, actually.  I'm giving you all free car.  It's actually kind of true.  So if you have an MSDN subscription with Azure, and  you have an MSDN subscription, and you haven't  activated your Azure, whatever it is, credit as part of the  MSDN subscription, they're actually running a  promotion right now.  And as a chance you'll win an Aston Martin if you go to this  URL.  So if you haven't activated Azure on your subscription,  there's never a better time than now to get your Aston  Martin.  That's actually a real thing, not a joke.  All right, so enough talking.  Let's jump into the code here and see how we build one of  these things.  So the first thing I'm going to do is head over to the  Azure portal, which is where all good things start.  So I go to the Mobile Services tab here on the left.  It's this little icon that looks like a phone with a  little sugar cube inside of it.  And here's all my apps that I've listed.  So I created just a few minutes ago this testing app.  It's completely empty.  It doesn't have anything.  But I just want to give you an idea of the experience of  starting out with mobile services.  So it's a blank app.  All I did is say Create.  And then I see here the choice of the different client  platforms.  So I get to decide how I want to get started with mobile  services, which platform I'm going to use.  Let's say I'm trying to write an Android application.  So I'll click on Android.  And we have this kind of contextual getting started  experience here with three easy steps.  The first step is it tells me go ahead and install the  Android developer tools, because you need that to  write Android apps.  Then I can create a table to store my data.  So it's just I click this button, and it's going to do  this to do items.  So it's going to be like a to-do list application.  And it says I already created it.  If it wasn't there, it would have created it for me.  And then I can download a pre-populated, pre-configured  Android application that I can get started with.  So I can go hit Download, and it'll just bring this zip  file down.  It's about a megabyte.  Very easy.  I've already done that.  And because my emulator is super slow, I went into Eclipse.  I imported my app here with our mobile library here.  Mobile Services Library.  And then I started up in the emulator.  And this is what you're going to get right out of the box  without doing any work, is this cloud connected app.  And so I can go and add something here.  Let's say give my talk.  Add an item to the list.  And then I can go and also mark something completed.  It's always risky doing on stage, because these emulators  have very particular networking requirements.  And sometimes it'll drop off without knowing why.  So I'm making changes to my server data.  And if I just head back to the portal here and click on this  data tab, I see the to-do item table I just created.  And I can actually browse all my items in real time, the  ones that are stored in my cloud back-end.  So here's the give my talk item I just created.  I can check in real time whether it made it.  So there you go, in just literally five minutes.  And you can have an app that you can take to your boss and  be like, look, we have an Android expense app now.  Finally, it's done.  Just change the title from to-do list to expenses.  And you're all expense approval and you're done.  So great.  So that's how you do the very basic thing, create a table.  Let's look at some of the other tabs here.  Actually, while I'm in the table itself with my data here,  there's this script tab.  And I talked about the server scripts that you can write.  So I can go ahead here and actually write a script for all  the four code operations against my data.  So if I want to validate that you're not allowed to do  list with swear words in it, or you're not allowed to submit  an expense for more than $1,000, I just  write a simple node script here.  Some of the other tabs, the scheduler, is where I do the  scheduled jobs that I mentioned.  Push and Identity is where I configure my push and  identity and authentication settings and things like that.  Logs is if my app generates logs in the server, we want to  make it very easy for you guys to see those logs.  You don't have to go remote into the VM and poke around  some folder somewhere.  We just bring them right here to the portal.  So that's kind of a very quick lap around mobile services and  the basic things it does.  Any questions before I dive into my game and show you how  that was built?  Question right there?  I'm sorry, I couldn't hear you.  Support for node on server scripts and for what exactly?  No, so currently our server, the question is do we support  anything else but node in our server scripting model?  Currently we only support node in our server scripts, but  it's definitely one of the top two or three things that  people ask for, especially if you're a.NET developer.  You're writing your Windows 8 app in.NET.  You want to write your server in.NET as well.  So that's something we're definitely looking at.  It's a little bit tricky though because we don't want to  scare away people that want to write Android apps and iOS  apps.  We picked node because it's kind of a neutral thing that  everybody's fine with.  If we made it.NET, we would have scared away a lot of people.  So we want to ideally have a choice for you and let you  pick which one.  Great, so let's go into my little app.  So here's, I've already pre-created it.  It's called Align 5.  Here's my errors from before.  But the first thing we want to look at is kind of my data  tab here.  And so my app, my game is powered by these two tables,  my games and then my players.  So when somebody first opens my game and they type in their  credentials, I create a little player record for them in  this players table.  And the games table just contains a record of all  the ongoing games.  So pretty easy.  Let's jump into Visual Studio here.  So I think I have the phone one and the Win 8 one open  side by side.  This is the Win 8 one.  So the first thing I needed to do is in my Win 8 app, I need  to add a reference to the mobile services SDK.  So we're actually up on NuGet.  So if you go to manage NuGet packages, you can see the  package I referenced, basically, which is  windowsazure.mobileServices.  That's our package.  And we've tried to be, remember going back to that  simplicity with enablement thing.  We don't want to really tie your hands and implement  everything in a little closed box that you can't look  inside.  So we've taken advantage of a lot of the community packages  that are out there.  Instead of using our own serialization, we use json.net.  Instead of writing our own HTTP client, we use the HTTP  client that ships with the framework.  We support portable class libraries, which is a great  way to make the same code actually run across a bunch  of different C-sharp platforms.  This is why you can easily write ASP.net code as well  using RSDK, because we use portable libraries.  So that's great.  This is pretty new.  It's been only out there for a month or two, our NuGet package.  So that's the first step.  By out of the NuGet package.  And then I need to configure my connection information.  So if I go back to the Quick Start here and say I'm using  Windows Store, I need to have the URL in the application key  so that my application can talk to the mobile service.  So it's just right in here.  And I've pasted it inside my VS instance.  I've put it in kind of a little config file somewhere,  because I didn't want to accidentally check it into  source control or anything.  So I put it in a little separate file here.  And then I created an instance of mobile service client, which  is kind of your entry point into using mobile services.  I just created it here and pulled in the URI and the  application key.  So I have my instance here.  Now I can use it from anywhere inside the app.  So the first thing I'm going to do is in that page where I  list the games.  Let's find that.  Main page.  I create references to these two tables that I showed you,  the game table and the player table.  And I use the mobile service client that I put in my app  static class.  And then I have these two local objects, the game object and  the player object.  So if I go to the game object, you'll notice they're just  polkos, plain old C-sharp objects.  Nothing special here.  I've added some JSON.net serialization attributes,  because I prefer to lowercase my properties, but that's  really a personal preference.  You don't need to add these attributes.  It's pretty simple classes, right?  Just game and the names of the players and things like that.  So that's pretty easy.  But the one thing that I want to draw your attention to is in  the portal.  I didn't ask me anywhere when I create these tables, my  games and my players.  This is how I create a new table if I wanted to.  It doesn't ask me anywhere, OK, what columns do you want?  What schema do you want for your table?  And that's one of the cool things that Mobile Services does  for you is it will actually look at the object that's  coming in on the wire, the JSON.  It will just try to infer what database columns it needs to  create.  So actually, we call it auto schema or default schema.  It will just infer based on what's coming in and  pre-populate your table for you, which is a huge time  saver if you're quickly prototyping an app.  Then when you go to production, you want to turn that off,  because you don't want just some random person with  Fiddler going in and adding a bunch of new database columns.  So you want to turn off that feature in some of the  configure tab.  Or maybe on the enable dynamic schema.  So you just go ahead and turn that off when you're done  with your development.  OK, so we went through.  And then let's see the actual, so how do we actually  insert into this table?  Let's go down here.  I'll skip a few of these.  Let's go this refresh method.  And that's the method that fires whenever somebody goes  on that page, basically, after they've authenticated and  done all that stuff.  So I'm using link on the client, which is actually  pretty sweet.  So the open games are just games that player one is set  to something, but player two is not set to something.  So that's how you know it's an open game.  And then my games are the games where I'm either player  one or I'm player two.  But it's a pretty ugly looking link query.  Imagine how hard that would be if you had to write a  SQL.  I mean, it probably wouldn't be that hard if you're a  SQL expert.  But we try to make it super easy to do things like this.  And this is link on the client, but actually gets  serialized and run on your server.  So it's not running client side.  It's actually running server side.  So it's easy, but also performs pretty well.  So that's how you just load up a bunch of stuff.  And then I call two list async.  So I put my link query, and then I terminate it with  something like that.  So we can give you a list, or if you want, we also have two  collection async.  And we have two incremental loading collection.  And these are a bunch of really nice convenience things  we added.  If you want to bind to that control and winnate, the  infinite scrolling thing, you just use one of our  collections that does it out of the box.  You don't have to worry about implementing all the loading  events and all that.  We try to make that super easy.  So we covered loading stuff into it.  Let's look at updating something.  So I go against my table, and there's an update async  method, pass it the new updated table, very straightforward.  Insert as well, very straightforward.  Just insert async.  I pass it a new object instance.  In this case, a blank game.  If they click New Game, I just create a new blank game and  insert it.  So that's kind of the basics of the data model on the client.  Now let's look at the way we do scripts on the server.  So if I go back to, let's say, the games table here, and  then I go to the scripts.  Let's look at the scripts I actually have.  So here's the insert script, which happens when someone  tries to create a new game.  Let's go kind of piece by piece.  So you'll notice it's kind of a set shape.  It has to be called insert, the little function.  It has to have these three parameters.  First parameter is the thing that they pass me on the  wire, deserialized.  The second thing is the user object, which is something  as part of our authentication model, which I'll talk  about later.  And request is a handle to the incoming and outgoing HTTP  request, so you can read things like headers, and you can go  and write stuff out to the response directly if you'd  like.  Then I start modifying the object that came in in my  script.  So I'm not going to trust their own ID.  Like if they want to pretend to be a different user, so I'll  use kind of our authentication to get the right ID.  I'm not going to trust the one they configured.  I put the state here, which is where I store the actual  grid and where each move has happened.  Who the active player is.  I remove some properties.  Then I call request.execute, which is how I tell mobile  services, OK, I'm done with this object.  Go ahead and process your pipeline going forward and  insert it in the database.  If I want to run some code after the insert completes  into the database, I can add a little callback here and  I'll fire after the complete is done.  So insert is pretty straightforward.  If I go into update, update is kind of the biggest method  here.  It's kind of huge.  My entire game loop is inside this update method.  It's a little bit cheating, but let's see what it does.  So when they send me an update with a new instance of the  game object, I'm not going to trust the game object they  sent me, so I'll use this local reference to game table to  pull it from the database.  So if I want to access another table from inside these  scripts, I use kind of this tables global.  And I say get table.  That's kind of how I get a reference to the  table on the server.  So I get my own instance.  And here's a little query syntax.  I say where, and then I can pass an object here, and it'll  just do an equality comparison.  So I'll say, OK, the item they tried to insert, give me the  real one.  I don't want to trust the one they gave me.  And then when it completes, you call the read method to  run the query.  And then when it asynchronously completes this  success callback will fire.  Results will be in this property, obviously.  And then I can check here, for example, if there aren't  any results.  So they're trying to update a game that doesn't exist.  I'm just going to go ahead with a request object and just  return a 404 right away.  So this is a good example of say, OK, I want to break out  of the pipeline.  I want to say, I'm done processing this.  Let's just move on and return a 404.  Like there's something wrong with this request.  So that's how I abort the pipeline.  And if there is actually any results, I say, OK, the game  is the first result, because obviously the ID is the primary  key, so it has to be the first one.  And then depending on what they're doing, whether it's  the first time they try to become the second player, I  say, OK, they're trying to join the game.  Or if there's already a second player, they're trying to  probably make a move.  It's a little bit silly, my game logic.  That's not why you're here to look at my crappy JavaScript.  But you kind of get a sense of how you write these  server scripts.  And they're not as scary as you might think.  And we have great documentation in our developer  center where you can go and kind of see with the learn a  little bit more about the syntax.  So we've covered kind of the data stuff.  Let me see if there's anything else.  I think that's pretty much all I had when it comes to data.  Do you guys have any questions so far about how to handle data?  Probably somebody's going to ask me, can I use table storage  instead of SQL?  Because this actually uses SQL server in the back end.  The answer is not right now.  We're looking into it.  That's another very common question.  Yep, over there.  I'm sorry?  I can just video it back end.  Right.  So the question is, can I just use my own back end instead of  the database that we generate for you?  That's a really good question.  And that's really useful if you already have an existing  back end.  Say you have an on-premise application.  Now someone's telling you, I want a cloud version of that.  Or actually, no, they're telling you, I want a mobile  version of that.  So how do you do it?  We currently don't support it kind of in a first class way.  If your SQL server schema for your table is kind of in a  very expected format, it will work.  We give you a way to specify a connection string to a  different database.  But you have to follow our own convention about what your  tables are called and all of that.  In the future, definitely.  Kind of one of the big things in the next six to 12 months  for us is kind of enabling these hybrid enterprise  scenarios, so either using your own database.  Or what's also interesting is from within your server script,  using something like a service bus relay to just talk into  your enterprise to an existing data store that you don't  want to host up in Azure.  So the expense app is actually a good example.  You don't want to host the expense data up in Azure.  You don't want to copy it.  You just want to kind of open just one pipe just to that  server from the cloud.  And you don't want anybody else to have access to that.  So that's definitely something that's not there today.  But we're looking at that.  Question?  Can you access the SQL Azure from another server?  Yeah, so the SQL server I'll show you, actually.  We don't swallow it.  Like we don't hide it from you.  So if you go back to the portal, if I go up here to my  configure, I think, you'll see it tells you, OK, it's the  SQL database on this SQL server.  So I can just click this arrow and actually take me to the  SQL tab in the portal.  And I can go and open the SQL management studio and go and  look at it myself.  So you can back it up and do all those things.  So we covered data.  That's kind of the first thing we always talk about.  And then let's talk about auth.  And this is where a lot of people fall asleep a little  bit, so tell me if you're super bored.  So the main, I'm going to go into the slide, the main goal  with auth is to authenticate the app user in the app itself.  So you can kind of customize it, show their little smiley  face in the corner and put their name, hello, so and so.  But also what's more important, actually, more  interesting is to authenticate them on the server.  So we can have their identity on the server.  And then based on that, we can do authorization.  And we can create some kind of rules on the server and  things like that.  So at the end of these authentication flows, we want  to have their identity both on the client and the server.  So our first authentication flow is what we call server  auth.  And this is kind of an OAuth 2-based flow using a  little browser widget that we invoke.  So when you call a login API on mobile service client, and  it'll kind of open a little browser, and they'll type in  their credentials, you saw me do that in the phone app.  So that's kind of the server flow.  And it's super simple.  It's just one line of code.  The developer types their credentials directly into  the kind of the website, like a live ID or Facebook.  And then the auth provider, still using the browser, will  kind of redirect this authentication token back to  the mobile service back end.  So that's how we get the identity.  And then mobile service will pass back to you some parts of  that identity.  So now you know who the person is, their user ID.  So this is kind of the simplest way to do authentication.  It uses this little browser control.  You don't need an SDK from the auth provider.  You don't need to figure out live connect or any of those  things.  This is very easy, but a little bit limited.  Because mobile services is the one who manages the  authentication token.  So if you want to add extra permissions to it, you want to  say, I want access to their basic information and their  pictures maybe also.  You can't really do that, because we  manage the token for you.  So if you want to do graph access against Facebook or  Twitter, it's kind of limited what you can get using this  flow.  But it is very quick.  That's kind of why it's the first one we talk about.  We also have a client flow that relies on kind of a device  specific, provider specific SDK.  So a good example of that is on Windows 8, if I use the  live connect SDK, it actually does single sign on for me.  So when you saw my Win8 app, I didn't have to type in  anything.  I'm logged in with my live ID.  The app knows exactly who I am.  But for that, I have to use a native SDK for live connect.  The same for Google and Android, right?  They'll do single sign on.  The same for Twitter does that.  But I know definitely, I think Facebook does it on iOS.  Facebook has kind of a built in thing on iOS that can  authenticate you.  So if you want to take advantage of these capabilities,  we enable you to do that.  So you'll type in your credentials in whatever  their SDK does.  It may have some native prompt or I don't know what it does.  At this point, mobile services is not involved.  And it'll send you back a token.  So now you know who the user is.  And you requested that token.  So you could say, well, I want permission to access their  picture library, their friends, their social security  number, their credit card.  You can add all those claims to the token because you  requested it.  And then you give it to mobile services so we can also get  the identity of the user.  So this is kind of a little bit trickier because you need to  understand how their auth SDK works.  And it's quite a bit more code.  But it's powerful because now that token, because you  requested it, you can put all the things on it and have  quite rich graph access both on the client and on the server.  So depending on your needs, if you just want something  quick and dirty, use a server flow with the iFrame and  kind of passive OAuth.  If you want single sign on or rich graph access, you'd  probably use the client authentication.  I know this is a little bit dense.  So let me show you some code here.  Here's the, I skipped over the authentication method before.  I'll show it to you now.  Authenticate, there it is.  So in this live auth client, so that comes from this reference  I added over here to the live SDK.  So I had to pull in the live SDK for win8.  So I use, and this is boilerplate code from their  documentation.  I had to use the live auth client.  And I call login on their client.  And then when their authentication flow is done,  I call this login with Microsoft account.  That's how I pass, and then, sorry, you can't see it very  well here, I pass the authentication token that  they gave me in the result.  I pass that back to mobile services so I can  authenticate on the server.  I could take this token now on the client and continue  using it against live to get even more stuff about that user.  So that's how it looks on Windows 8.  On Windows phone, it is very similar.  It's just a few tiny differences, but largely the  same SDK.  So you can go here, find the authenticate method.  You notice it's kind of the same shape, and I end up  doing the same thing.  Just pass mobile services authentication token now.  So this is the client flow because I want that nice  single sign on.  Now, if I wanted to do the server flow, let me show you  how really easy that is.  So I'd say something like, you know, get a reference to my  client here, and then I do client login.  So notice I'm using a different overload of login.  So I just call login async here.  And it takes the authentication provider.  So I'll say, you know, Facebook.  And then I need to await this call because it's synchronous.  And then by the time, because it's asynchronous, by the  time it's done, now here the user will already be  authenticated.  This login async will take care of popping up the browser,  doing all that dance, getting me back to identity.  So at that point, if I go and say client, it's current  user, I think.  Now, this current user object will give me a bunch of  information about the user, like their user ID.  And that's kind of their identity at this point.  So the moment the second line completes, I have all the  off on the client.  So you can see how it's much, much simpler.  But you get a little bit less by doing it this way.  Undo all this.  I'm going to break my demo.  So yeah, so I showed you the client flow and the server  flow from within a.NET app.  Now, the one thing that I didn't show you is this didn't  just work like that for free.  So there's a little bit of server configuration I need to  do here in mobile services.  So if I go inside my app here, I go to the Identity tab.  You notice I've pasted these two values for the Microsoft  account.  So you know when you create an app with these off  providers, they need to know who you are, who's trying to  authenticate.  So they ask you to go to their little portal and create  like a manifestation of what you're doing.  So you register there and they ask you who you are.  And so they know when people are trying to log in, what are  you logging into?  And when people log into your app, they'll see a little  screen saying, so and so I was trying to get your  authentication token to talk to a bunch of our resources.  And it says who you are.  So to do this, I went to this LiveConnect developer center.  And this is a little bit tricky.  The UX is not great, but it's documented really well on our  Dev Center.  So I created an application here.  And then the key things that it gave me are the client ID and  the client secret.  So these are the two things I went and then I go ahead and  pasted the two of them into my window here.  And just a minute on why this client secret is important.  This is to prevent spoofing.  So if mobile services receives a token, it needs to have a  way to verify that that token was actually issued by the  authentication provider, not just some other person sitting  in the middle.  So it's a shared secret model.  So this client secret is known both to Live and to Mobile  Services.  And you don't ever want to put it in the client, even those  called client secret.  You never want to do that.  It's a server thing that sits there.  And so when Live sends that token, it signs it with the  secret.  And then when Mobile Services receives it, it knows to  check that signature using this client secret.  It's kind of like a symmetric key kind of thing.  So that's how we make sure that we can actually trust that  token.  So when you get something past your user object, you know  that's been verified because we've checked it against this  client secret.  So speaking of that, let's see what's the model in  server script to do authorization.  So say someone's authenticated, right?  How do I tell Mobile Services, OK, only let authenticated  people see my data?  Don't let anybody else see my data.  So if I go to my permissions column here on my games table,  you'll notice I have kind of a drop down with a few choices.  Everyone is hardly ever used.  Anybody with an application key is the default.  So that's pretty much, you should consider that to be  equivalent to everyone.  Because the application key is not really secret.  That's something that's bundled into your app in the  store.  And somebody can download it, reverse engineer it.  So you don't want to consider this really like any sort of  authorization mechanism.  What you really want to do is say only authenticated users.  And then you know that people have gone through that  authentication flow.  And they've presented a valid token that's signed with a  correct secret.  So this is how I can protect different operations on my  table and say, OK, only authenticated people can go  ahead and access these.  This is very coarse.  Like this is only on the operation level.  So within an operation, let's see how I can make some more  kind of fine-grained decisions.  So if I go back to that insert script, somewhere down here,  I have a piece of code.  So this little thing here.  So I have a record of whose turn it is in the game.  And you don't want to be able to tell me, OK, well, actually  it's my turn.  And it's my turn again.  So you kind of play yourself all the time.  You want to actually protect the other player's turn.  So they can try and tell me, OK, I am the active player.  But we don't trust that.  We actually go and say, OK, user.userID.  So we get the ID from the authentication flow to make  sure they're not pretending to be the other user.  So that's an example where we do this.  That's kind of usually how you do this.  Also, you'll notice in the players table, I actually  keep a record of this user ID.  So this is how if somebody logs in, this is how I know  they're kind of the same person.  When they log in, I always get the same user ID.  And so I can associate all their push settings and their  name and all that.  So that's kind of how I keep a record of them  using that user ID.  And I only get the user ID if I can figure the off flow.  So that's pretty much it for off.  Is there any questions?  I know it's a little bit quick, but it's a little bit  boring also.  See a question back there.  You're going to have to speak really loud, because I can't  hear you at all.  I don't have the Android version of this particular app,  but I can show you of the login.  Yeah, absolutely.  That's actually a really good point.  So the question is, how does this look in Android?  And we've tried to maintain symmetry across all of our SDK.  So ideally, if you can write it in.NET, you should be able  to write it in Android.  So I haven't done this before, but I will go over to our Dev  Center and get the answer for you.  So if you go in here, we have our authentication tutorial.  So you say, get started with authentication.  And I'm going to pick Android here, right at the top.  And then I'll scroll down here.  So there's a little bit of setup and stuff like that.  I'll actually find the piece of code where you call login.  So there it is, right?  So client is the client instance that I created of my  mobile services client.  I call login.  I have the same choice of authentication provider.  And then async code looks a little bit different in Android.  They don't have a wait, but they have this callback style  programming.  So this callback fires asynchronously when the thing  completes.  And then on completed, I get a reference to the user.  So code looks very similar if you exclude the platform  specific things.  So I love our Dev Center.  It's great.  And we have a cheat sheet for all different clients.  And you can go and if you want to see how you do this in iOS,  which is all going to look like spaghetti to me if I try to  actually understand it.  But somewhere here, there will be something that looks like a  login.  Maybe it's this one.  I guess?  I mean, really?  That's it, I think.  It's true.  OK, great.  So we're done with authentication.  Let's move on to the kind of the fun part, the push  notifications.  You had a question?  How about your own authentication mechanism, like  KD?  Yeah, so that's a great question.  The question is, can you have your own  authentication mechanism?  The short answer is currently we don't give you one out of  the box.  Currently, there's kind of my fellow PM Josh Twist.  He has a blog post where he talks about how to do custom  authentication.  It's kind of going back to this enablement thing.  It's very, it's a little bit manual, but you can do it.  Going forward, we're definitely considering like a first  class thing where you're going to go and federate with  Active Directory, make it super easy, kind of the  simplicity part.  Currently, we're kind of the enablement part when it comes  to custom auth.  And then we want to get back to the simple thing to enable  that as well.  Currently, no, though.  Currently, almost.  Yeah, I don't think if, I don't know if anybody has done it  with Active Directory.  People have done kind of custom auth like where you have your  own table, where you manage username's passwords with the  right hashing and all of that.  I don't know for sure that anybody has done Active  Directory.  So maybe you'll be the first.  And you'll send me an email after.  And then I'll talk about it.  And people will think I'm smart.  So how does push notifications work?  So you're probably familiar that all the different phone  vendors have their own push notification service.  So Microsoft has two, actually, because we're extra  special.  We have WNS for Windows 8, and we have MPNS for phone 8.  So that's how you push to those devices.  Apple has APNS or APN.  GCM is for Google.  And the regular flow, the way you would do this is, imagine  you don't even have mobile services in the pictures.  The first thing is the device through some magic out of  band way registers for a push channel.  So I don't know how they do it.  Is it HTTP, or is it something like in the network, in the  cellular network?  I don't know how it does it.  But it basically checks in with the authentication service  and says, OK, here I am.  I'm ready to receive push notifications about something.  And what it gets in return is this channel, which is kind of  its address.  So if somebody wants to send a push notifications, it can go  back to the notification service with that channel and  say, send this guy something.  So the way we normally do this is, so then the device  registers for channel, then sends it back to mobile  services.  And mobile services will stash it away in a table  somewhere for later use.  Probably will stash it with a person's user ID.  So then we can later say, OK, this person needs a push  notification.  So you look up their channel, and you go ahead and you send  them a notification directly with the  notification service.  This is great.  It's very simple.  But you can see how this will quickly start to fall apart  if you are talking about really massive scale here.  So the one problem with this is if you have a million users  of your app, and you want to send a single push  notifications to all million users, how many calls are  you going to be making for mobile services?  A million, right?  You'll be making a call for every single  notification you want to send.  So this is great for small scale.  And if you don't have these large blasts of  notifications where everybody has to get the same one, if  it's always the custom notification that's always  very specific to just one person, then you're not really  wasting much.  But if you're broadcasting the same thing to a lot of  people, this gets really tedious.  So for that, we have this integration with another Azure  feature called notification hubs.  How many of you have heard about notification hubs?  Very few.  So it's this extra service that takes away some of this  channel management and pushing for you.  It's kind of this separate little infrastructure piece that  takes that away.  So the flow starts the same way.  So you'll register your channel with the push service.  Then instead of giving it to mobile services, and then you  use the developer and mobile services, you have to now  create a table and manage it, you give it to notification  hubs, and you label it with a tag.  So you say, my funky app, or people that should get  notifications about app update or something.  You create a descriptive tag that describes a group of  people that you want to add this to.  And then all mobile service has to do is send a single call  to that tag saying, OK, everybody who's listening for  app updates, I have my new version, I have a bug.  You just send one notification to the tag.  And notification hubs is responsible for delivering  the million notifications through the respective  notification service to the million devices that have  registered for that tag.  So it's kind of a mechanism to deliver push at scale.  So notification hubs will do the heavy lifting for you, so  then you don't have to do it in your mobile service script.  Let's go ahead and do a quick demo, because I only have 12  minutes left.  So let's go inside my Windows 8 app here.  How many of you have done push notifications with Windows 8  so I can maybe skip over?  OK, not very few.  OK, a lot.  So let's go to this check registration method.  So this stuff here is kind of standard Windows 8 stuff.  So you say, OK, this is kind of the black magic where the  Windows 8 app talks to the notification service and  registers.  I don't know what happens in this call, but all I know is I  get a channel back.  And that's a URI that we can now use to address the phone.  And then I actually stuff it right inside my player object.  So I have this WNS property.  It's in the player table where I had all my registered  players, and I just send it to the channel URI.  So that's all I need to do on the server to capture the  channel and send it to the back end.  On the phone, it's exactly the same except the property is  called MPNS channel.  OK, now the interesting part is how do I actually deliver the  notification from my back end?  So if I go here, I probably guessed that it's inside that  giant update script in my game table,  such as everything else.  So somewhere down here, I have a function that I think  right at the bottom.  There it is.  So this is a function to deliver a toast notification.  So you'll notice I use this tables object again.  I get my players table from within my game update.  And then this is the power of this node model and this  JavaScript server model.  Like I'm actually talking to a different table now from the  script for this table.  It lets me combine things easily.  So I get my players table here.  I pull up the records for that user ID.  Or there's actually going to be a unique record because user  IDs are unique.  And then I go ahead and I pull up the channel.  So I say, OK, here's the WNS channel.  It's just living in that property.  The MPNS channel is living in that property.  And then we have this very simple API.  So we say push.wns, pass the channel, pass your message.  And it's pretty much symmetric across the WNS and MPNS.  And it's pretty much symmetric across APNS and GCM as well.  It's very similar looking.  So it's very easy to do it this way.  I had to do one little piece of config here, which is again  required for the push notification service and  mobile service to establish a trust relationship.  So for Windows, I had to paste these credentials from  one of the portals.  It's documented in our docs.  MPNS actually doesn't require, it throttles you at 500  notifications per device per day.  So they've said, OK, we don't care if you, we just got  to throttle you.  You don't need to authenticate.  Apple actually uses a sockets-based connection to  the notification service.  So they actually ask you to upload a certificate to  authenticate that you get from their portal.  And Google has just an API key similar to WNS.  So this is kind of where you configure the push, and that's  just that one line in the script to send the notification.  For notification hubs, I didn't have a demo prepared,  because it's not fully baked in to mobile services yet.  But I can show you kind of a slightly more advanced way to  do it, which is, like I mentioned in Node, it's  kind of an extensible thing.  And it has similar to NPM.  It has a package manager called NPM.  And one of the packages on there is the Azure package,  which actually my team ships as well.  And the Azure package has support for a lot of these  Azure services.  So if you want to talk from your mobile service back end to  blob storage or table storage, you'd use this Azure package.  And so you can use notification hubs through the Azure package.  So you just reference it.  It's already in the box.  You just have to say, require Azure to pull it into scope.  And then you kind of create your notification hub  reference.  And then this is how basically you send to, if you just use  this syntax, so WNS, send whatever, this whole thing  here, you'll send it to all people that are subscribed to  that hub.  This first parameter, if you specify a string there or a  comma-separated list of strings, then that's where you  specify the tag, or set of tags you want to push to.  If you pass null, it's everybody.  If you pass a set of tags, you'll just push to those tags.  So again, easy to do that a little bit more advanced,  because you have to use an external module.  It's not kind of in the box.  But it's easy to reference it.  OK.  So let's kind of push at a glance.  And with that, I'm kind of done with our coding demo.  Any questions on push?  We spent a little bit of time talking about the timeline  and where we're headed with this.  OK.  So like I said, I think mobile service has been around  for less than a year.  First, we launched our preview with support for Windows 8.  That was kind of the first thing we did.  These core scenarios, the data often push.  Then we quickly kind of added iOS support, Windows Phone 8  support after that.  This was, I think, towards the end of last year.  Then early this year, we added a schedule or in support for  command line tooling.  That's not even something I showed you.  But instead of using the portal, you can do a lot of  that stuff from command line tooling.  It was very recently, about two, three months ago, we added  HTML client, notification hubs, Android support.  So you see it's kind of very incremental and we're building  up on our capabilities.  Today, literally today, about six hours ago, we lit up  support for custom API and source control.  So I'll just kind of show you in the portal where those are.  And don't tweet about it until Scott blogs.  And then you can all re-blog him.  But this is where you do a custom API.  A custom API is kind of like a powerful kind of HTTP only  script.  So for example, if you want to have a submit shopping cart  kind of thing, where do you put that?  Because that requires updating your list of widgets or  whatever you're shipping.  And it requires updating your customer table.  It requires kind of touching multiple tables.  It doesn't make sense really as an insert or update.  You see I had that problem with my game script a little bit.  My game update, I was putting everything inside the update.  So if you have these kind of bigger pieces of script that  kind of touch multiple tables, you can just create an HTTP,  just the random HTTP API, like submit, order.  And then you can configure different permissions for the  different HTTP operations here.  And you can just write your script in a very familiar way.  The other thing that literally shipped today is support for  source control.  So a lot of you may have found it kind of frustrating to edit  the scripts in the Azure portal.  You don't have to anymore.  You just go through the set up source control thing.  And I'm not going to go through it.  It's a very scary message, actually.  It says, do you want to enable source control?  This is a preview feature.  We recommend that you back up your scripts regularly.  So that's pretty intimidating.  But if you press that button, you can use Git to push your  scripts to your service after backing them up regularly.  So these are kind of the two new things.  And then there's kind of a bunch of  question marks after that.  What happens after this?  So I can't tell you the order of these boxes, but I can tell  you what's in some of them.  One of the big ones that is on our mind is general  availability for the service.  You saw the preview tags everywhere, and kind of the  preview language.  We're looking to make mobile services generally available  sometime this year.  So you can kind of put the full backing of Azure with  compliance and disaster recovery and all those things  built right in so you can really trust us with your data.  Another thing is kind of this set of enterprise scenarios  that I already talked about, basically connecting to an  existing data store, connecting to an on-premise data  store.  So that's another big direction.  A third big direction is what we call brand applications.  So we realize a lot of developers out there, a lot of  studios and consultancies out there, really have this kind  of same sort of requirement.  They'll have a customer come and say, build this very cool  app that really showcases kind of our brand.  Might not be super feature rich, but we need something  quickly out there for people to sign up for our fishing  ships campaign.  It needs to be catchy, but we need to get it done quickly.  So we want to tailor for those scenarios as well.  So kind of agencies and then enterprises, big directions  going forward for mobile services.  And that doesn't mean if you're just an indie developer  doing a game with mobile services like I did, that  doesn't mean that's not OK.  You can still do that.  We're still going to support you just the same.  But that's kind of where the big new feature areas are  going to be.  Great.  Already touched on this, but in your server scripts, if  you want to use Pusher to send push notifications to web  browsers, or you want to use SendGrid to send email, or  use Twilio to send SMS, we have these partnerships  through the Azure Store.  So if I go ahead and go into the Azure Store here, I can go  ahead and I already have a Pusher extension that I've  added before, but I can go ahead and add a new extension  here so I can pull in, let's say SendGrid if I want my  server script to send some email, let's go find it in the  list here.  And we automatically configure the billing  relationship with SendGrid.  Of course, a lot of these are free to start.  SendGrid is free for the first couple of thousand emails or  something like that.  But after that, you'll just get one bill from Microsoft.  The SendGrid stuff is going to get added to the bill.  You don't have to go and separately register.  So that's kind of a neat thing.  And last but not least, our customers.  We've seen quite good adoption of mobile services,  especially in Windows 8.  It's hard to make the argument to Android and iOS  developers to come and use a Microsoft product and use  something with Windows in its name.  It's a little bit of a hard sell for us.  But as you've seen, the platform itself, there's  nothing really Windows specific.  All the APIs I showed you, they all work on  Android and they all work on iOS.  So there's nothing about mobile services, and we use  Node on the back end.  So there's nothing that traps you into the Microsoft  ecosystem if you want to do an iOS app or an Android app.  It's just been slightly tricky to get  that message across.  So please spread the word.  One of our very exciting apps in the store is actually  VGTV.  And this is probably the one country where people know  what VGTV is, right?  There's no VGTV.  Please tell me someone knows.  OK, good, OK.  All right, good.  Yeah, so they're a TV channel and a website, I think, or a  website that's trying to turn into a TV channel, or  something like that.  But they have a great app and they really use everything.  They use data.  They use push notifications.  It's a great app.  You can go and grab it in the store right now.  So with that, go ahead and sign up.  We have a short URL.  If you go to windowsazure.com.  You can sign up for our service.  And with that, I'm pretty much out of time.  Thank you very much for staying with us.  Out of time, thank you very much for staying around for the  last session.  Please go ahead and give me any feedback.  Send me an email if you loved it or you hated it.  If you need more information, my Twitter and Facebook are  on there.  I can write my, sorry, my Twitter and blog are on there.  I can write my email address for you if you have a  question.  But other than that, thank you very much.  And we have unlimited time for questions since it's the  last session.  So you can be here all night.  You don't have to go to the party.  This is the parties right here.
Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_0_1535.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_1536_1583.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_1584_3515.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_3516_3899.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_3900_4631.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_4632_4679.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_4680_7883.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_7884_8363.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_8364_8891.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_8892_9395.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_9396_9971.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_9972_19007.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_19008_19139.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_19140_19235.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_19236_19511.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_19512_23423.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_23424_24347.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_24348_24395.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_24396_24443.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_24444_26231.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_26232_26375.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_26376_27419.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_27420_29303.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_29304_29387.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_29388_29843.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_29844_30143.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_30144_30215.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_30216_31235.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_31236_31811.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_31812_31883.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_31884_31943.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_31944_32483.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_32484_32903.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_32904_33383.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_33384_33551.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_33552_34043.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_34044_34715.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_34716_35531.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_35532_35651.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_35652_36707.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_36708_37667.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_37668_38495.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_38496_40679.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_40680_41795.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_41796_43883.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_43884_44087.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_44088_44711.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_44712_45959.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_45960_47051.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_47052_51323.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_51324_51431.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_51432_53051.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_53052_59195.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_59196_60755.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_60756_61499.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_61500_62255.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_62256_62339.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_62340_62411.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_62412_62843.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_62844_62903.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_62904_63335.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_63336_63455.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_63456_64463.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_64464_64895.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_64896_65087.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_65088_65219.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_65220_65267.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_65268_65435.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_65436_65531.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_65532_66479.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_66480_72731.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_72732_72983.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_72984_74015.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_74016_74123.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_74124_74231.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_74232_75431.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_75432_77483.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_77484_80027.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_80028_80123.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_80124_80339.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_80340_80699.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_80700_80999.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_81000_81239.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_81240_81443.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_81444_82115.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_82116_82199.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_82200_82415.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_82416_82571.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_82572_82847.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_82848_84287.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_84288_87239.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_87240_90107.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_90108_90335.png Yavor_Georgiev_-_Leave_the_backend_to_us_-_building_mobile_apps_with_Azure_Mobile_Services-68334930_90336_91254.png