I’m Kevin Moore.
I work on the Dart and Flutter teams at Google.
Building applications with Flutter is great.
You get amazing flexibility and fast developer cycles,
and now support for six platforms: iOS, Android, Web, Windows, Mac, and Linux.
But it's rare for an application to be an island.
Connections to services is what brings an application to life.
Aside from the Chess Timer App I use with my kids,
I can't think of an application I use that's not somehow connected.
You can use the Google APIs package to access over 180 different services
from your Flutter and Dart applications.
This talk will get you started.
Here's the outline of what I'll be covering.
Let's get started.
Google APIs can be broken into two categories.
There are APIs for engaging with user data.
So think email, contacts, tasks, books, fitness,
even YouTube favorites.
And there are APIs for Cloud services,
so think storage, BigQuery, compute, Kubernetes engine,
Memcache, translation, and many more.
Let’s get started by authenticating a user with a Flutter application
and getting their favorite YouTube videos.
Now. this talk is pretty short.
My goal is to get you excited about what’s possible,
so I’m going to skim over some details here,
but don’t panic, though.
you can visit flutter.dev/go/google-apis
for a step-by-step guide on how to get started.
Here’s the checklist of what we need to do to configure our application.
We'll start out by creating a Google Cloud project.
This allows Google to know about you and your application.
Now, if you already have a Firebase application,
you already have a Google Cloud project, and you may not even know it.
Next, we need to enable the API you'd like to use.
In this example, let’s enable the YouTube data API version 3.
Now, because we’re going to access user data, we need to have the user authenticate.
Google Cloud uses OAuth for this.
You need to configure authorization for each platform you went to support.
Now, today I’m going to be showing you how to configure a Flutter web application,
but our documentation explains how to configure applications
for mobile and desktop as well.
In our case, we’re going to go with a web application.
Make sure to put in your local development host so things work while testing.
Local host at port 8080 is a good one.
When you’re ready for production, you’ll put your production host here as well.
Since we’re setting up our application to access user data,
there’s a review process that you’ll have to go through
before any user can use your application.
While you’re experimenting and testing, you can simply pre-authorize
some test accounts you plan to use during development.
You can see Add Users button here under Test Users.
Now that everything is configured, let’s move on to the code.
With a Flutter web application,
you configure your client ID in the app’s HTML head tag.
Then you can move on to the Dart code.
All of the 180 APIs are in the Google APIs package,
and you can find that on pub.dev.
This package is generated from API descriptions provided by each service team,
so we will keep it fresh with the newest APIs and the latest features.
We import the YouTube V3 library.
You can see the library we import there, and we need to create YouTube API objects,
but where do we get the client?
This is where sign-in enters the picture.
To get an authenticated HTTP client, we need to authenticate the user.
This links back to all the work we did to set up our project.
We create an instance of Google sign-in, and we provide the scopes we want to access.
In this case, we want read only access to YouTube data,
so youtubeReadonlyScope is used.
Notice that the scope is hanging off the class we want to use.
In this case, YouTube API.
Again, scopes allow us to negotiate the access rights
our code will have to the user data.
Now, how does our application know authentication has finished?
Well, Google sign-in provides an event to watch for user change.
Listen to this event onCurrentUserChanged.
When the user is not null,
we have a successful login and we can get the videos.
Now that we’re signed in,
we can get an authenticated HTTP client from Google sign-in.
We create a YouTube API. Then you get favorites.
Remember, these APIs are generated from generic descriptions,
so make sure to read the documentation to understand how to use the API properly.
In this case, list, there’s some magic seeming parameters
that you have to use.
I think LL here stands for like list, for instance.
Once you have the favorites, we can use setState to store the video information.
Now that we have a signed-in user with video data, let’s create a UI.
GoogleUserCircleAvatar is a widget provided by the Google sign-in package
that lets us display the current user.
We can use a list view to display all of our favorite videos.
On the web, this is the flow. Pick your user, or sign in as someone else.
You see a notification that this app hasn't been verified.
This is where the test accounts come in.
You won’t see this dialogue once your application has been approved
and it’s in production.
Now you give the app permission to view your YouTube account.
This is where the scopes come in.
You only requested the read only scope, so you see the prompt is explicitly
for view your YouTube account.
Finally, you see all the data that the application will have access to.
And here's where we end up.
This is a list of my favorite YouTube videos. And of course, YouTube is just one example.
There are so many things you can do with these user data APIs.
An example is I made an application to look at my Gmail inbox
and search for all of the emails with the word unsubscribe in them.
Then I could roll up all the senders
and make a really easy experience to clean out my inbox.
There's lots of really cool stuff you can do here.
Again. I know that was quick, but I wanted to give you a flavor
of the steps you need to take to get things working.
The full walkthrough is online, and we’ll make sure that it’s up to date
as we evolve these APIs.
That’s user data and OAuth.
Now I’m going to take some time to show you Google APIs and Dart on the Cloud.
Earlier, I discussed these two classes of APIs.
We showed how to access user-focused data
from a client application, but that's just the start.
There are dozens of services provided by Google
that you can use to enable all sorts of scenarios.
Think of Pub/Sub, BigQuery, memorystore, translation,
text to speech, speech to text, and many more.
But we need to stop a second and consider the right way to access these APIs.
It’s fine for a user device to access user data once authenticated,
just like we did in the demo application,
but you probably don't want your end users directly accessing backend services.
You want to create your service account credentials privately
and not deploy them in an end user application.
So, you'll want a service sitting in the middle
that can be accessed by your client app using user credentials
that then connects to a backend API using service credentials.
Now, wouldn’t it be nice if you could use the same language
for your front end and your backend?
As I discussed in the What’s New in Flutter session in I/O,
we've been running Dart on Google Cloud
to support the Dart and Flutter ecosystems for years.
Sites like DartPad.dev and pub.dev handle thousands of concurrent users
and millions of daily requests, all with Dart on Google Cloud.
You can create a fully containerized Hello World app with Dart in 10 lines of code
and deploy it in under five minutes with Google Cloud Run.
But let's move beyond Hello World and access some services from our backend.
Now Firebase, specifically Cloud Firestore, is a great example of an API
that you may want to access both directly from a client and via a service.
Let me explain.
It’s already pretty easy to use Cloud Firestore in your Flutter application
with the Cloud Firestore package.
And you can use Cloud Firestore rules
to restrict user read and write permissions to only their data.
But sometimes you want tight control over how data is updated in Firestore.
Maybe you want to ensure votes or visits are accurately calculated.
Maybe you want to make sure only legal moves can be made in a multiplayer game.
These are times when you may want to introduce a service
that runs your trusted code to modify sensitive data in Firestore
while still giving users read-only access to the data that is displayed as it’s updated.
Let’s look at an example of using Cloud Firestore from a Dart service
running on Cloud Run.
To keep things simple, I’m just going to increment a counter in a transaction.
So just like we did before, we need to create an API object
from an authenticated HTTP client.
We get our API object from the Google APIs package just like before.
Firestore API is a class we want to create.
And just like before, it exposes the required scopes needed for the client.
Creating the authenticated HTTP client is a bit different on the backend, though.
We use the Google APIs off package and a wordy but powerful function,
clientViaApplicationDefaultCredentials.
Now, this API is smart.
It knows how to access your local Google Cloud credentials
if you’re using the Google Cloud SDK on your development machine,
then when you deploy your application, it uses the metadata server that’s exposed
on every Cloud run instance to access the necessary service accounts.
This means the code you develop is the same code that you deploy,
and you don’t need to worry about having secrets or keys
being accidentally committed to get or pushed to a production server.
Just like in our Hello World example, we use package:shelf as our server library.
When we get a request, we make a call to the Firebase API
with a transaction that increments our hit count.
Then we send the response to the client as JSON.
Then it’s just a simple matter of a couple of G Cloud commands
to build and deploy our application.
Now that our application is hosted,
you can see that when I make a request, my service runs the transaction
and sends back detailed information about how it was executed.
You can also see the counter on the Firebase dashboard update as I make requests.
Now, there were a few details I didn’t cover today,
like setting up the service accounts to access the APIs, but don’t worry.
the source code for both the Hello World demo and the Firebase counter,
plus a lot more, is at dart.dev/go/cloud.
Now that we've looked at Google APIs on both the client and the server,
I want to take a minute to look forward.
The Google APIs libraries are currently based on adjacent RPC mechanism.
We’re investigating how we can improve
the performance of these APIs by integrating with gRPC.
gRPC is a high-performance RPC mechanism championed by Google.
We already have gRPC libraries for Dart and code generators that can create Dart classes
and service endpoints from a gRPC service subscription.
So keep an eye on this space.
We are also investigating deeper integration with offerings like Cloud Functions
to make it easier to reuse your client code on serverless backends.
Again, keep an eye on this space
and check out dart.dev/go/cloud for the latest details.
So to summarize, we have all of the pieces you need to access dozens of user-focused
Google APIs from your Flutter applications.
We also provide the building blocks to build Dart-based services on Google Cloud
powered by some amazing backend APIs.
We can’t wait to see what you build.
Please make sure you check out these other Flutter sessions at /IO this year,
and thanks for watching.