[RUM][Mobile + Web] Custom attribute's value is being updated
toussam opened this issue ยท 9 comments
Hi ๐
Describe what happened
We are tracking views and providing additional information using custom attributes. Among them, we have attributes provided for specific views and others who are "general" custom attributes being applied on all views' tracking using the rum's addAttribute method.
We noticed that if we set up or update a "general" custom attribute after tracking a view then the said custom attribute's value linked to this last event will be updated.
Steps to reproduce the issue:
- set up a custom attribute using the addAttribute method (we used a string type for the attribute's value)
- track a view using the startView method
- update the custom attribute with a different value
- notice that the custom attribute displayed into the rum's view event is set with the updated value
Describe what you expected:
The tracked view event's should contain the custom attribute with the initial value and not the updated one.
Additional context
- Dart/Flutter version: 3.2.6 / 3.16.9
- Android/iOS OS version: any? - currently handling iOS 13.0+ and Android 6.0+ (and noticed on Web too)
- Device Model: any
- Datadog SDK version: 2.2.0
- Versions of any other relevant dependencies: N/A
Thanks in advance for your investigation and future response. ๐
Best regards,
Hi @toussam,
So I can be clear on what you're expecting -- for a global attribute added through DatadogSdk.instance.rum?.addAttribute
, you're expecting a view to have the value of the attribute when it started, even if that attribute is changed during the life of the view?
Hi @fuzzybinary,
This is indeed the behavior that I was expecting / trying to reach.
Now that you're referring the view's lifecyle, it does make sense. So I presume that the only way to do so would be to set up the custom method for each event using the startView method's third parameter (attributes), am I right?
If so, I did tried this solution and it worked for Android, but sadly not for iOS. I just tested back and I can confirm you that the custom attribute's value is still being updated for the view event.
Also, using this solution, I noticed the #565 issue for the Web.
Yes, the behavior you were seeing was expected. Attributes are considered a stateful property of the view, so changing them updates the property in the view. However, we do capture the current state of the global attributes at certain points of the view, it's just RUM will always show you its last known value.
I'm surprised that using the attributes parameter of startView
didn't work for iOS -- can you supply some code that reproduces the issue you're seeing? iOS and Android should behave the same.
How you approach this depends on what you're trying to track. Can you give me more information about your use case?
@toussam Following up on this -- The original bug is as designed, but I'd still like to make sure startView
is working as expected on iOS. Do you have an example of it not working as expected?
Hi @fuzzybinary,
Sorry for the late response.
I thought I could provide a sample sooner, but I had a busy week.
Will test things back and try to provide you something ASAP.
Hi @fuzzybinary,
Again, sorry the late response.
Just tested back and can confirm to you the described behavior when not using "global" attributes and so by providing them "manually" when calling the "startView" RUM's method.
Here are a few lines to reproduce the said issue on iOS platform:
int _index = 0;
Future<void> track(String eventName) {
// Uncomment the below line and comment the class member to test the "local variable case"
//int index = 0;
final Map<String, dynamic> properties = {"test": "test_{$_index}"};
index++;
try {
_datadog.rum?.startView(eventName, null, properties);
} on Exception catch (ex) {
debugPrint(ex.toString());
}
}
Steps to follow:
- launch your app
- display the first page that will call the "tracking" method to track itself
- push a new page which will also track itself
- wait for the events to be uploaded on DG
- observe the custom attributes' value for both events
In our case, we don't update the custom attributes right away like for the index. Indeed, before pushing a new page into our navigating system, we have most of the time some "behind work" in which we will update some data or whatever. Real life examples would be signing in or updating the user's email for example.
Observed behaviors:
- on iOS
when using the class property, the provided value is "test_0" for the first page (checked using a breakpoint), the observed value on DG is "test_0" in a first time (if you're quick enough) then quickly become "test_1" after refreshing DG dashboard.
when using the local property, the provided and observed value will (obviously!) be the same aka "test_0".
- on Android
when using the class property AND when using the local property, the provided and observed value will be the same aka "test_0".
I understand that global attributes are considered stateful properties. I don't know if it's also the case for the one provided manually for each tracking events, but our needs is to track some data at T time (aka tracking time) and it's a bit weird to not have the same behavior on both platforms so again not sure if there is a real issue here.
Let me know if you need more information or anything.
Best regards,
Hi @toussam,
Thanks for doing the legwork here. I'll take a look into it. If the platforms are not behaving the same that is definitely a bug I want to look into.
I'll see if I can figure out what's going on and hopefully have an answer to you soon.
Thanks again for the reporting!
@toussam Is it possible you're sending multiple startView
events with the same name? From an initial investigation, I think it's possible that iOS isn't reporting the new view if it has the same name, and instead updates the properties on the original view. On Android it creates two views.
I'll investigate more why iOS isn't behaving the same way here, looking to see if you're making those duplicate calls might give you a workaround. Alternately, calling stopView
manually may give you the same behavior between the two platforms.
Hi @fuzzybinary,
It's technically possible, yes. As explained into my previous message we're tracking our views therefore if you go back, you will have two events with the same name, but to be honest with you when I tested back I did so following a standard flow from our app in which I didn't do any backward navigation so when observing my issue, each events had a different name.
Thank you for your investigation and response! ๐
EDIT/ Just tested calling the "stopView" method right after the "startView" one as suggested and it's indeed giving the same behavior as for the Android platform. ๐