title: How To Use Async/Await/Coroutines In OnCompleteListener Firebase
body: <p>I am building a client application which uses Firebase for two things:</p>
  <ul>
  <li>User Authentication</li>
  <li>Using a realtime database</li>
  </ul>
  <p>I have managed to set up everything correctly on my client and on my backend server (using Firebase's Admin SDK) and am able to correctly authenticate users and allow them to read/write to the database.</p>
  <p>I am also using Retrofit2 to send requests from the client to the backend.</p>
  <p>As part of allowing users access to the database, it is needed to send the user's token to the backend so the user can be verified.</p>
  <p>To do this, I have the following logic:</p>
  <pre><code>val user = FirebaseAuth.getInstance().currentUser
  
      if (user != null) {
          user.getIdToken(false).addOnCompleteListener {
              if (it.isSuccessful) {
                  val token = it.result?.token
                  //retrofit logic to send request happens from here
              }
         }
  </code></pre>
  <p>As you can see, getting the Id token of the user is an asynchronous call and in the current code base that I have, I have this code block for each one of my calls to the backend (duplication).</p>
  <p><strong>I want to know how I can export this snippet to a function (maybe a suspend method?) so that it can be reused for every call to the backend</strong></p>
  <p>I have searched online and have seen many SO questions, but none that fit this scenario.
  I have thought about passing in a callback, but I have several methods that communicate to the backend, and each of them will require a different callback method.</p>
  <p>The solution I am looking for looks something like this:</p>
  <pre><code>fun fetchDataFromDB() {
    getIdTokenForUser()
    //wait till it finishes and then
    //perform request to DB
  }
  
  fun updateDataInDB() {
    getIdTokenForUser()
    //wait till it finishes and then
    //perform request to DB
  }
  
  //......
  </code></pre>
  <p>I have tried reading about and implementing coroutines, but I lack the knowledge to do so correctly.</p>
  <p><em><strong>EDIT</strong></em></p>
  <p>Thanks to @Doug Stevenson for his answer and direction, I have managed to construct the following:</p>
  <pre><code>private suspend fun getUserIdToken(user: FirebaseUser) = coroutineScope {
  
      val job = async {
          user.getIdToken(false).result?.token
      }
      job.await()
  }
  </code></pre>
  <p>And I use it in this fashion:</p>
  <pre><code>fun updateDB(context: Context) = runBlocking {
  
      val user = FirebaseAuth.getInstance().currentUser
  
      if (user != null) {
          val token = getUserIdToken(user)
      }
  
    }
  </code></pre>
  <p><strong>Is this the correct approach?</strong> Since the answers given below present a different implementation.</p>