0

I am new to Firestore / Document DB / NoSQL, so please be patient with me on this.

I have something like below where a document is created in the "Users" collection when user sign in for the first time

class FirestoreService{

   private val db = Firebase.firestore
   private var userExists:Int = 0
   private var documentRef = ""

   fun addUser(user: User) {

         // check if the user exists
         db.collection("Users")
            .whereEqualTo("Email", user.email).get()
            .addOnSuccessListener { documents ->
               // async, so following variables will not be initialized when         
               // synchronous code is being called

             for (document in documents) {
                  documentRef = document.id
                  userExists = if(docRef!=null)  1 else 0
              }
                 
                
            }
            .addOnFailureListener { e ->
                Log.w(TAG, "Error adding User document", e)
            }

 
     if (userExists == 0){

        val userHashMap = hashMapOf(
         "name" to user.name,
         "email" to user.email,
         "notif" to false
    )
    
        db.collection("Users")
        .add(userHashMap)
        .addOnSuccessListener { documentReference ->
                 Log.d(TAG, "User document added!")
                 Log.d(TAG, "DocumentSnapshot added with ID: ${documentReference.id}")

            }
         .addOnFailureListener { e ->
             Log.w(TAG, "Error adding User document", e)
         }
        }
     }


     fun updateUser(user:User){

         db.collection("Users")
            .document(documentRef)
            .set({
                "notif" to user.settings?.notifOn
            })
            .addOnSuccessListener { Log.d(TAG, "User DocumentSnapshot successfully updated!") }
            .addOnFailureListener { e -> Log.w(TAG, "Error updating User document", e) }

      }

}

Inside a fragment

// inside fragment method
val firestoreService = FirestoreService()
firestoreService.addUser(user);

// inside another fragment method
firestoreService.updateUser(user2)

As you can see I am setting variables inside addOnSuccessListener which is asynchronous so the synchronous if condition and updateUser calls do not work as expected (required values may not be assigned to the userExists, documentRef when synchrnous code being called). As I know these async behavior is handled using callbacks like mentioned in here. But I am not sure how to make it work in my case with addOnSuccessListener?

user158
  • 12,852
  • 7
  • 62
  • 94
  • What's wrong with the shared code? – Alex Mamo Mar 01 '22 at 11:42
  • @AlexMamo I have already mentioned it below below the question – user158 Mar 01 '22 at 12:17
  • @AlexMamo I update the question bit, in case my text was not clear. As an answer to your question : required values may not be assigned to the `userExists`, `documentRef` when synchronous code being called – user158 Mar 01 '22 at 12:25
  • There is no way you can use the value of `userExists` outside the onSuccess. Firebase API is asynchronous. So please check the duplicate to see how can you solve this using a callback. And since you are using Kotlin, you might also be interested in reading this article, [How to read data from Cloud Firestore using get()?](https://medium.com/firebase-tips-tricks/how-to-read-data-from-cloud-firestore-using-get-bf03b6ee4953). – Alex Mamo Mar 01 '22 at 13:50

0 Answers0