My app is failing the Static Analysis test with the following error:
All authenticated channels must use the Request for Information (getUserData) API call to obtain a user's email address during the sign-up or sign-in flow.
Originally I was trying to use:
GetPartialUserData("email", {context: "signin"})
Which works great (it's actually even more relevant for my case), except that it's failing the Static Analysis. I tried swapping it out for getUserData() but still no luck. Same error.
The flow when you open the app is:
So if you're not signed in, it's a direct path from launch to getUserData() without user interaction, yet I'm still failing the Static Analysis test.
I've already read over the pertinent information in the following pages:
But I still have no clue why it's failing.
How can I implement this correctly to pass the test?
Finally figured it out. I was going off the incorrect examples shown in the third link I posted above, which has you create a Store object like:
store = CreateObject("roChannelStore")
And then call methods on that Store object like this:
userData = store.GetUserData()
However this is incorrect!
Fortunately I ran across this blog post which alludes to the fact that the way I was trying it is the old way of doing it (as of 2016, yet Roku still shows it in the docs but won't allow it to pass Static Analysis!)
https://blog.roku.com/developer/channelstore-node-billing-guide
The correct way to implement "getUserData" is to create a Store node like this:
store = CreateObject("roSGNode", "ChannelStore")
Then you can set which pieces of data you want to get, and then set the command field to the method name you want to call as a String:
store.command = "getUserData"
Then listen to (observe) the userData field and set a callback to be run once the data is retrieved.
Here's an example of the full flow showing how to get only the email from the user for use in a login screen:
sub Init() m.store = CreateObject("roSGNode", "ChannelStore") info = CreateObject("roSGNode", "ContentNode") info.addFields({context: "signin"}) m.store.requestedUserDataInfo = info m.store.requestedUserData = "email" m.store.command = "getUserData" m.store.observefield("userData", "OnEmail") end sub sub OnEmail() if m.store.userData <> invalid email = m.store.userData.email
' Do something with the email here end if end sub
This finally passed the Static Analysis. Hopefully this helps some poor soul Googling down the road.
Finally figured it out. I was going off the incorrect examples shown in the third link I posted above, which has you create a Store object like:
store = CreateObject("roChannelStore")
And then call methods on that Store object like this:
userData = store.GetUserData()
However this is incorrect!
Fortunately I ran across this blog post which alludes to the fact that the way I was trying it is the old way of doing it (as of 2016, yet Roku still shows it in the docs but won't allow it to pass Static Analysis!)
https://blog.roku.com/developer/channelstore-node-billing-guide
The correct way to implement "getUserData" is to create a Store node like this:
store = CreateObject("roSGNode", "ChannelStore")
Then you can set which pieces of data you want to get, and then set the command field to the method name you want to call as a String:
store.command = "getUserData"
Then listen to (observe) the userData field and set a callback to be run once the data is retrieved.
Here's an example of the full flow showing how to get only the email from the user for use in a login screen:
sub Init() m.store = CreateObject("roSGNode", "ChannelStore") info = CreateObject("roSGNode", "ContentNode") info.addFields({context: "signin"}) m.store.requestedUserDataInfo = info m.store.requestedUserData = "email" m.store.command = "getUserData" m.store.observefield("userData", "OnEmail") end sub sub OnEmail() if m.store.userData <> invalid email = m.store.userData.email
' Do something with the email here end if end sub
This finally passed the Static Analysis. Hopefully this helps some poor soul Googling down the road.
Thanks for letting everyone know!
I was one of poor souls that needed that answer thank you so much.
This code isn't working for me. OnEmail gets called but m.store is invalid.
have you created it right
m.store = CreateObject("roSGNode", "ChannelStore")
like this, Or you can just make it global in MainScene.brs file like this:
This worked for us got rid of that error in static analysis.
Hello, I am using my instant channel package because I have no clue what I am doing and I don't know where to input this information at to get rid of my error. Can you please help me?