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

Build and scale serverless mobile apps with Firebase and Google Cloud

Build and scale serverless mobile apps with Firebase and Google Cloud

If your app has millions of users, you need a backend infrastructure to support its growth. Do you want to build that infrastructure? Of course not! Your time is better spent focusing on the app. In this talk, we'll take a look at the code for a mobile app that works like a “universal translator”. It uses Firebase and Google Cloud services and APIs. And we'll do it "serverless" without having to manage servers or infrastructure.

Doug Stevenson

June 06, 2019
Tweet

More Decks by Doug Stevenson

Other Decks in Technology

Transcript

  1. Build and scale
    serverless mobile
    apps with Firebase
    and Google Cloud
    Doug Stevenson
    @CodingDoug

    View full-size slide

  2. Doug Stevenson
    Language is hard!

    View full-size slide

  3. Doug Stevenson

    View full-size slide

  4. Hello!
    Bonjour!

    View full-size slide

  5. API
    Service
    App
    Server

    View full-size slide

  6. API
    Service
    App

    View full-size slide

  7. Build better apps
    Auth
    Cloud
    Functions
    Cloud
    Firestore
    Hosting
    ML Kit
    Realtime
    Database
    Cloud
    Storage
    Improve app quality
    Crashlytics
    Performance
    Monitoring
    Test Lab
    Grow your app
    Analytics
    Predictions
    Cloud
    Messaging
    Remote
    Config
    A/B Testing
    Dynamic
    Links
    In-app
    Messaging
    bit.ly/what-is-firebase

    View full-size slide

  8. Cloud
    Storage
    App
    Cloud
    Functions
    Cloud
    Firestore
    Cloud
    Speech API Translation API
    Hello!
    Bonjour!

    View full-size slide

  9. Firebase Authentication
    ● Every user gets a unique ID
    ● Restrict who can read and write what data
    ● Give each user a personal space to work with
    ● Create your own audit trails

    View full-size slide

  10. Firebase Authentication login
    startActivityForResult(
    AuthUI.getInstance()
    .createSignInIntentBuilder()
    .setAvailableProviders(listOf(
    AuthUI.IdpConfig.GoogleBuilder().build(),
    AuthUI.IdpConfig.EmailBuilder().build()
    ))
    .build(),
    RC_SIGN_IN)

    View full-size slide

  11. Firebase Authentication login
    override fun onActivityResult(reqCode: Int, resCode: Int, data: Intent) {
    super.onActivityResult(reqCode, resCode, data)
    if (reqCode == RC_SIGN_IN) {
    if (resCode == Activity.RESULT_OK) {
    // Login success
    user = auth.currentUser
    }
    else {
    // Login error
    }
    }
    }

    View full-size slide

  12. Cloud Firestore
    ● Cloud-hosted
    ● NoSQL
    ● Realtime
    ● Mobile access controlled with security rules

    View full-size slide

  13. Uploads
    upload1
    - language: "en"
    - url: "gs://bucket/upload1"
    upload2
    - language: "es"
    - url: "gs://bucket/upload2"
    upload3
    - language: "ja"
    - url: "gs://bucket/upload3"
    Collection
    Document
    Fields

    View full-size slide

  14. Add speech metadata to Firestore
    val recording = Recording()
    recording.contentType = "audio/amr"
    recording.encoding = "AMR"
    recording.sampleRate = 8000
    recording.language = "en"

    View full-size slide

  15. Add speech metadata to Firestore
    val recording = Recording()
    recording.contentType = "audio/amr"
    recording.encoding = "AMR"
    recording.sampleRate = 8000
    recording.language = "en"
    val firestore = FirebaseFirestore.getInstance()
    val docRef = firestore.collection("uploads").document()

    View full-size slide

  16. Add speech metadata to Firestore
    val recording = Recording()
    recording.contentType = "audio/amr"
    recording.encoding = "AMR"
    recording.sampleRate = 8000
    recording.language = "en"
    val firestore = FirebaseFirestore.getInstance()
    val docRef = firestore.collection("uploads").document()
    docRef.set(recording)
    .addOnSuccessListener { ... }
    .addOnFailureListener { e -> ...}

    View full-size slide

  17. App
    Cloud
    Firestore

    View full-size slide

  18. Cloud Storage for Firebase
    ● Uploads and downloads direct from app
    ● Robust
    ● Secure
    ● Mobile access controlled with security rules

    View full-size slide

  19. Upload speech file to Cloud Storage
    val storage = FirebaseStorage.getInstance()
    val storageRef = storage.reference
    .child("uploads")
    .child(user!!.uid)
    .child(docRef.id)

    View full-size slide

  20. Upload speech file to Cloud Storage
    val storage = FirebaseStorage.getInstance()
    val storageRef = storage.reference
    .child("uploads")
    .child(user!!.uid)
    .child(docRef.id)
    storageRef.putFile(Uri.fromFile(recordingFile))
    .addOnSuccessListener { ... }
    .addOnFailureListener { ... }

    View full-size slide

  21. Cloud
    Storage
    App
    Cloud
    Firestore

    View full-size slide

  22. Cloud
    Storage
    Cloud
    Firestore
    Transcribe
    & Translate

    View full-size slide

  23. Cloud Speech
    API
    Cloud Translation
    API

    View full-size slide

  24. Cloud
    Storage
    App
    Cloud
    Firestore
    Cloud
    Speech API Translation API

    View full-size slide

  25. API
    Service
    App
    Server

    View full-size slide

  26. Cloud Functions
    ● Deploy code that responds to events
    ● Fully managed node.js environment
    ● Pay only for what you use
    ● Secure

    View full-size slide

  27. Cloud Functions Triggers
    ● HTTP endpoint
    ● Google Cloud Storage
    ● Pub/sub topic message
    ● Cloud Firestore

    View full-size slide

  28. Additional Firebase Triggers
    ● Realtime Database
    ● Authentication
    ● Google Analytics for Firebase
    ● Crashlytics
    ● Remote Config
    ● Test Lab
    ● Scheduled (cron)

    View full-size slide

  29. Cloud
    Storage
    App
    Cloud
    Functions
    Cloud
    Firestore
    Cloud
    Speech API Translation API

    View full-size slide

  30. Cloud Functions Storage trigger
    export const onRecordingUpload =
    functions.storage.object().onFinalize(async (object, context) => {
    // Plenty of code here that performs the translations!
    })

    View full-size slide

  31. Handle input
    const path = object.name // path: uploads/{uid}/{docId}
    const parts = path.split('/')
    if (parts.length !== 3) {
    console.log("Path isn't three parts long")
    return
    }
    const docId = parts[2]

    View full-size slide

  32. Read speech metadata from Firestore
    const docRef = firestore.collection('uploads').doc(docId)
    const snapshot = await docRef.get()
    const docData = snapshot.data()

    View full-size slide

  33. Read speech metadata from Firestore
    const docRef = firestore.collection('uploads').doc(docId)
    const snapshot = await docRef.get()
    const docData = snapshot.data()
    const languageCode = docData.language
    const sampleRateHertz = docData.sampleRate
    const encoding = docData.encoding

    View full-size slide

  34. Call Speech and Translate APIs
    const recognizeRequest = {
    config: { languageCode, sampleRateHertz, encoding },
    audio: { uri : `gs://${bucket.name}${docData.storagePath}`}
    }

    View full-size slide

  35. Call Speech and Translate APIs
    const recognizeRequest = {
    config: { languageCode, sampleRateHertz, encoding },
    audio: { uri : `gs://${bucket.name}${docData.storagePath}`}
    }
    const recognizeResponse = await speechClient.recognize(recognizeRequest)
    const transcript =
    recognizeResponse[0].results[0].alternatives[0].transcript

    View full-size slide

  36. Call Speech and Translate APIs
    const recognizeRequest = {
    config: { languageCode, sampleRateHertz, encoding },
    audio: { uri : `gs://${bucket.name}${docData.storagePath}`}
    }
    const recognizeResponse = await speechClient.recognize(recognizeRequest)
    const transcript =
    recognizeResponse[0].results[0].alternatives[0].transcript
    // Foreach language to translate:
    translate.translate(transcript, { from: fromLanguage, to: toLanguage })

    View full-size slide

  37. Call Speech and Translate APIs
    // Assemble final translations object
    // const translations = {
    // "ja": "こんにちは世界",
    // "es": "Hola Mundo",
    // "nl": "Hallo Wereld"
    // }
    await docRef.update({ translations })

    View full-size slide

  38. Cloud
    Storage
    App
    Cloud
    Functions
    Cloud
    Firestore
    Cloud
    Speech API Translation API

    View full-size slide

  39. Translation API

    View full-size slide

  40. Cloud
    Storage
    App
    Cloud
    Functions
    Cloud
    Firestore
    Cloud
    Speech API Translation API

    View full-size slide

  41. Query for latest speech document
    const uploads = firebase.firestore().collection('uploads')
    uploads
    .where('timeCreated', '>', new Date())
    .orderBy('timeCreated', 'desc')
    .limit(1)
    .get()
    .then(snapshot => ...)

    View full-size slide

  42. Query for latest speech document
    const uploads = firebase.firestore().collection('uploads')
    uploads
    .where('timeCreated', '>', new Date())
    .orderBy('timeCreated', 'desc')
    .limit(1)
    .get()
    .then(snapshot => ...)

    View full-size slide

  43. Receive realtime updates to results
    const uploads = firebase.firestore().collection('uploads')
    const unsubscribe = uploads
    .where('timeCreated', '>', new Date())
    .orderBy('timeCreated', 'desc')
    .limit(1)
    // .get()
    .onSnapshot(onNext)
    function onNext(querySnapshot) {
    // querySnapshot contains updated search results
    }

    View full-size slide

  44. Cloud
    Storage
    App
    Cloud
    Functions
    Cloud
    Firestore
    Cloud
    Speech API Translation API
    Hello!
    Bonjour!

    View full-size slide

  45. How do you scale it?
    You do nothing.

    View full-size slide

  46. Cloud Firestore Scaling
    ● Massively scalable
    ● Queries scale with the size of the result set
    ○ ~ 50 in 1,000
    ○ ~ 50 in 100,000
    ○ ~ 50 in 100,000,000
    ● Firestore will not perform an unscalable query

    View full-size slide

  47. Cloud Storage Scaling
    ● Exabyte scale
    ○ 1 with 18 zeros after it (1x1018)
    ○ 1 million terabytes
    ○ Trillions of high-res photos

    View full-size slide

  48. Cloud Functions Scaling
    ● Auto scales up and down
    ● Up to 1000 concurrent server instances for each
    background trigger
    ● Bandwidth- and rate-limited scaling for HTTP
    triggers

    View full-size slide

  49. Thank you!
    Doug Stevenson
    @CodingDoug
    github.com/CodingDoug/universal-translator
    Get the code:

    View full-size slide