0

I can do an atomic/multi-location update in Swift using NSNull() to delete multiple refs. How can I do the same thing in Kotlin using a null type?

let followersRef = "followers/\(otherUserId)/\(currentUserId)"
let followingRef = "following/\(currentUserId)/\(otherUserId)"
let someOtherRef = "someNode/\(currentUserId)"

var multiLocationDict = [String: Any]()
multiLocationDict.updateValue(NSNull(), forKey: followersRef) // <- NSNull() value that deletes this entire ref
multiLocationDict.updateValue(NSNull(), forKey: followingRef) // <-NSNull() value that deletes this entire ref
multiLocationDict.updateValue(1, forKey: someOtherRef) // <- Actual Value that updates or creates another ref

let rootRef = Database().database().reference()
rootRef.updateChildValues(multiLocationDict, withCompletionBlock: { (error, ref) in
    // ...
})

Just for a little more clarity in Swift the dictionaries can accept NSNull(). So this works in Swift to delete a ref/path using NSNull(). See an example here

let pathToDelete = "/someRef/\(uid)/someValue"

var dict = [String:Any]()
dict.updateValue(NSNull(), forKey: pathToDelete)

firebaseRootRef.updateChildValues(dict)

But this doesn't work in Kotlin

val pathToDelete = "/someRef/$uid/someValue"

var map = mutableMapOf<String, Any>()
map[pathToDelete] = null

firebaseRootRef.updateChildren(map)
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
  • @Tenfour04 `atomic` meaning update multiple nodes at once. See here https://firebase.blog/posts/2015/09/introducing-multi-location-updates-and_86, https://stackoverflow.com/a/56203185/4833705, https://stackoverflow.com/a/42035660/4833705 – Lance Samaria May 05 '23 at 18:07
  • @Tenfour04 I do the Firebase atomic ref updates using NSNull() it in Swift, it definitely works. Here are some examples: https://stackoverflow.com/a/38466959/4833705, https://stackoverflow.com/a/49042980/4833705. The problem that I'm running into here is I'm not a native Kotlin dev, I'm just learning it and also learning to use it with Firebase – Lance Samaria May 05 '23 at 18:20
  • @Tenfour04 You see in this answer https://stackoverflow.com/a/38466959/4833705 it says `... is now an NSNull() object (not nil), and Firebase knows that NSNull is a nil value.`. I don't see Kotlin's version of NSNull(). I should've added an example but when I tried to add `null` to a `mutableMapOf` or `HashMap` it wouldn't let me. Example `var map = mutableMapOf()` ; `map[followersRef] = null`. I asked the question specifically about Firebase and maps because of what worked in Swift. – Lance Samaria May 05 '23 at 18:29
  • 1
    Oh, wait. You're using `NSNull` to clear some values, not to do some hack to achieve an atomic update, is that it? You just want to know how to clear values during an `updateChildValues` operation in Kotlin? – Tenfour04 May 05 '23 at 18:33
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/253500/discussion-between-lance-samaria-and-tenfour04). – Lance Samaria May 05 '23 at 18:34

1 Answers1

2

I am not sure what do you mean by "atomically update", because I do not see in your code any type of synchronization.

But you can use null value for variables in Kotlin which declared by type marked with ?. For instance, Any? type for your example and after that put null in a dictionary which holds Any? as value. Something like that:

val followersRef = "followers/$otherUserId/$currentUserId"
val followingRef = "following/$currentUserId/$otherUserId"
val someOtherRef = "someNode/$currentUserId"

val multiLocationMap = mapOf(
    followersRef to null,
    followingRef to null,
    someOtherRef to 1
)

// Then work with database
Mikhail Guliaev
  • 1,168
  • 1
  • 6
  • 14
  • `atomic` meaning update multiple nodes at once. See here https://firebase.blog/posts/2015/09/introducing-multi-location-updates-and_86, https://stackoverflow.com/a/56203185/4833705, https://stackoverflow.com/a/42035660/4833705 – Lance Samaria May 05 '23 at 18:09
  • this doesn't work. I tried it and firebase wouldn't accept it as in `rootRef.updateChildren(multiLocationMap)`. It was a mismatch error. Thanks for the suggestion :) – Lance Samaria May 05 '23 at 19:00
  • Can you clarify "mismatch error"? Are you getting a compile time error or runtime error? Based on the documentation for the `updateChilren` function, it looks like this *should* work. https://firebase.google.com/docs/reference/kotlin/com/google/firebase/database/DatabaseReference#updateChildren(java.util.Map%3Cjava.lang.String,java.lang.Object%3E) – Tenfour04 May 05 '23 at 19:10
  • @Tenfour04 It was a compile error. I stepped out for a sec, I'll message you and let you know the error once I come back. – Lance Samaria May 05 '23 at 19:21
  • @Tenfour04 I just tried it out, his answer worked. I had a compile error earlier, not sure what happened but it's working now. Thanks for the help :) – Lance Samaria May 06 '23 at 02:51
  • @MikhailGuliaev I must've did something wrong earlier, so please ignore my earlier comment because it's working fine now. Thanks for your answer :) – Lance Samaria May 06 '23 at 02:58