Static Analysis Failing Due to Lack of getUserData

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:

  • main.brs creates and shows the HomeScene.
  • HomeScene.xml/.brs starts a task to check if the user is signed in, and if not, presents the:
  • EmailSignInScreen.xml/.brs which runs the task that includes the getUserData() command.

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.

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:

m.global.AddField(“store”, “node”, false)
m.global.store = CreateObject(“roSGNode”, “ChannelStore”)

and then use m.global.store instead of m.store

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?