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 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
  2. 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
  3. 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 } } }
  4. App

  5. 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
  6. Add speech metadata to Firestore val recording = Recording() recording.contentType

    = "audio/amr" recording.encoding = "AMR" recording.sampleRate = 8000 recording.language = "en"
  7. 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()
  8. 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 -> ...}
  9. Cloud Storage for Firebase • Uploads and downloads direct from

    app • Robust • Secure • Mobile access controlled with security rules
  10. Upload speech file to Cloud Storage val storage = FirebaseStorage.getInstance()

    val storageRef = storage.reference .child("uploads") .child(user!!.uid) .child(docRef.id)
  11. 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 { ... }
  12. Cloud Functions • Deploy code that responds to events •

    Fully managed node.js environment • Pay only for what you use • Secure
  13. Cloud Functions Triggers • HTTP endpoint • Google Cloud Storage

    • Pub/sub topic message • Cloud Firestore
  14. Additional Firebase Triggers • Realtime Database • Authentication • Google

    Analytics for Firebase • Crashlytics • Remote Config • Test Lab • Scheduled (cron)
  15. 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]
  16. 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
  17. Call Speech and Translate APIs const recognizeRequest = { config:

    { languageCode, sampleRateHertz, encoding }, audio: { uri : `gs://${bucket.name}${docData.storagePath}`} }
  18. 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
  19. 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 })
  20. Call Speech and Translate APIs // Assemble final translations object

    // const translations = { // "ja": "こんにちは世界", // "es": "Hola Mundo", // "nl": "Hallo Wereld" // } await docRef.update({ translations })
  21. Query for latest speech document const uploads = firebase.firestore().collection('uploads') uploads

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

    .where('timeCreated', '>', new Date()) .orderBy('timeCreated', 'desc') .limit(1) .get() .then(snapshot => ...)
  23. 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 }
  24. 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
  25. Cloud Storage Scaling • Exabyte scale ◦ 1 with 18

    zeros after it (1x1018) ◦ 1 million terabytes ◦ Trillions of high-res photos
  26. 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