Android Question [SOLVED] List objects get changed

Computersmith64

Well-Known Member
Licensed User
Longtime User
I have a sub in my FirebaseMessaging service that sends a message (as a Map). When I pass a message to the sub for sending I also want to save it in a list so that if the send fails, I can retry later. If the send is successful, the message is removed from the list.

As you can see from the code below, the message map is actually 2 maps - a "to" map & a "data" map.

When I send the first message it saves to the list ok, however every subsequent message added to the list results in all the previous ones' "data" map being set to empty ("data={}") & only the most recent message has any value in the "data" map.

For example, here's the log output if I send 3 messages & then loop through the values in messageList:

'SEND FIRST MESSAGE
(MyMap) {to=/topics/92bb34ae-3d76-4096-ad83-9f7f7b187a1d-AllUpdates, data={type=pos, sendername=Nexus, message=First message, lat=-41.292606064478186, lon=174.02045622467995, timestamp=1502492750494, group=AllUpdates, senderuuid=92bb34ae-3d76-4096-ad83-9f7f7b187a1d}}

'SEND SECOND MESSAGE
(MyMap) {to=/topics/92bb34ae-3d76-4096-ad83-9f7f7b187a1d-AllUpdates, data={}} 'FIRST MESSAGE DATA IS NOW EMPTY
(MyMap) {to=/topics/92bb34ae-3d76-4096-ad83-9f7f7b187a1d-AllUpdates, data={type=pos, sendername=Nexus, message=Second message, lat=-41.29621733886542, lon=174.02380764484408, timestamp=1502492800319, group=AllUpdates, senderuuid=92bb34ae-3d76-4096-ad83-9f7f7b187a1d}}

'SEND THIRD MESSAGE
(MyMap) {to=/topics/92bb34ae-3d76-4096-ad83-9f7f7b187a1d-AllUpdates, data={}} 'FIRST MESSAGE DATA IS NOW EMPTY
(MyMap) {to=/topics/92bb34ae-3d76-4096-ad83-9f7f7b187a1d-AllUpdates, data={}} 'SECOND MESSAGE DATA IS NOW EMPTY
(MyMap) {to=/topics/92bb34ae-3d76-4096-ad83-9f7f7b187a1d-AllUpdates, data={type=pos, sendername=Nexus, message=Third message, lat=-41.2970213844652, lon=174.02977053076032, timestamp=1502492868097, group=AllUpdates, senderuuid=92bb34ae-3d76-4096-ad83-9f7f7b187a1d}}

I don't understand why this is happening! Is there some kind of limitation when it comes to saving maps of maps to lists?

Here's the code:

B4X:
Private Sub sendLocationMessage(msg As String, lat As Double, lon As Double, group As String)

    Private m As Map = CreateMap("to": $"/topics/${Starter.myUUID}-${group.Trim.Replace(" ", "")}"$)
    Private data As Map = CreateMap("type": "pos", "sendername": Starter.cOpts.MyName, "message": msg, "lat": lat, "lon": lon, "timestamp": DateTime.Now, "group": group.Trim.Replace(" ", ""), "senderuuid": Starter.myUUID)
    m.Put("data": data)
    CallSub2(FirebaseMessaging, "sendMessage", m)
End Sub

Public Sub sendMessage(message As Map)
    Private Job As HttpJob
    Private jg As JSONGenerator

'messageList is declared in Process_Globals
    If messageList.IndexOf(message) = -1 Then messageList.Add(message)
    Job.Initialize("fcm", Me)
    jg.Initialize(message)
    Job.PostString("https://fcm.googleapis.com/fcm/send", jg.ToString)
    Job.GetRequest.SetContentType("application/json")
    Job.GetRequest.SetHeader("Authorization", "key=" & Starter.API_KEY)
End Sub

- Colin.
 
Last edited:

stevel05

Expert
Licensed User
Longtime User
In a small test It seems to create the data OK.

Are you accessing the MessageList anywhere else in the app?
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
Why not save the raw JSON to the list instead?

B4X:
messageList.Add(jg.ToString)
Yeah, I could do that (& I might anyway) - but I'd like to know what the issue is with doing it the way I am. If it's a limitation that a List can't store a map with another map embedded in it, then at least I (& whoever else reads this thread) will know & not fall into that trap again. On the other hand, if it's a bug then Erel should know so it can be fixed.

Or maybe I'm slightly OCD & just need to know why this behavior occurs! :p

- Colin.
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
In a small test It seems to create the data OK.

Are you accessing the MessageList anywhere else in the app?
Normally I would be, but when I started having issues with it I commented out any other code that references messageList. So for the purposes of producing the log output I put in my first post, it's only those 2 subs (plus the one that calls sendLocationMessage of course - but that doesn't reference messageList).

It's really got me stumped...

- Colin.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
The attached project creates and reads data in the same format that you do. I had to falsify some of the data of course, but it reads the data map from within the main map OK.
 

Attachments

  • TestList.zip
    7.2 KB · Views: 141
Upvote 0

stevel05

Expert
Licensed User
Longtime User
BTW MessageList.IndexOf(Message) will always return -1 as you are creating a new Map each time.
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
The attached project creates and reads data in the same format that you do. I had to falsify some of the data of course, but it reads the data map from within the main map OK.
Thanks. I'll have a look at it in the morning (after midnight here & I'm in bed now!)

- Colin.
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
BTW MessageList.IndexOf(Message) will always return -1 as you are creating a new Map each time.
Under normal circumstances yes, but in the code that I've commented out while I debug this issue, in cases where the message send failed I iterate through messageList & retry sending any messages that are stored in it - hence the check so I don't add the message again if it's already there. If the send is successful, the message is removed from the list.

(But as I said, all that code is currently inactive while I debug this issue)

- Colin.
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
The attached project creates and reads data in the same format that you do. I had to falsify some of the data of course, but it reads the data map from within the main map OK.
When I tested your code with your data it worked fine, however I still had the same problem in my app with my data - but that led me to was some code (that I don't need now anyway) that I was using to check for duplicate messages.

In summary, I was declaring a map (lastLocationSent) in Globals, then assigning the data part of last message sent to it (lastLocationSent = message.Get("data")). When I went to send the next message, I would check that the current message & lastLocationSent were different & if they were, send the message, clear lastLocationSent & then save the current message to it. What I didn't realize is that it seems that initializing a Map by using Map = Map saves a reference not a copy. So of course when I called lastLocationSent.Clear, it was also deleting the data from the corresponding message in messageList...

Thanks for your efforts @stevel05 - you definitely helped me track down the cause of the issue.

- Colin.
 
Upvote 0
Top