Troubleshooting Recipe Configurations
If you're having trouble figuring out the right syntax for either the query
or matchList
parameters in either the category recipe or contents recipe, you can identify the content defined by the query
parameters using a breakpoint in a Java file and then running your app in debug mode. Using this debug approach, you can see exactly what the query
is selecting from your feed, and then you can more easily configure the matchList
parameter. This approach is helpful if you're trying to match elements with attributes or other confusing syntax, or if you just want to get a better sense of what the query
parameter is returning. The method described here shows you exactly what is returned in the queries you've configured in your recipes in Fire App Builder.
Choose the tab that corresponds with your feed's format.
To see what your Category and Contents recipe returns for a JSON feed:
- In the Android View, expand Gradle Scripts and double-click build.gradle (Module: app).
-
Locate the
debug
object and changetestCovergeEnabled
tofalse
, like this:debug { testCoverageEnabled false }
- Press Shift twice to bring up the Search Everywhere dialog box, and then type JsonParser.java to locate this file.
-
On line 144, where it says
return result;
, set a breakpoint by clicking once in the left gutter (just to the right of the "144" line number, in the empty column space).A red dot should appear, indicating the breakpoint at that point. When you run the app in debug mode, the code will stop at that breakpoint and show the contents of your Categories and Contents recipes.
-
Click the Debug 'app' button . Let Gradle build the app with the debugger.
-
When the build finishes, in the footer of the Android Studio window, click the Debug tab and the select the Debugger tab in the pane above to view the details.
After the app builds, look for the Variables to populate (as shown in the screenshots in the upcoming steps). (If the variables never populate, make sure that you have
json
as the value for theformat
property in your recipes. Otherwise, JsonParser.json never gets used.) -
To see the categories targeted by Categories recipe, expand the result variable. You'll see all the categories returned.
Note that in the above screenshot, the
query
variable shows the query that is being run (in your Categories recipe): in this case,$..categories[*]
.In the result, the items under
result
are the categories in the feed —Costa Rica Islands
,Costa Rica Underwater
, etc. - To see the contents targeted by the Contents recipe, click the Resume Program button (it appears to the left of the Debugger tab). The code then iterates to the next recipe (the Contents recipe) and returns the result.
-
In the Variables pane, click map, and then expand one of the items in the array (such as 0). You see all the properties targeted for your Contents recipe.
Note that the
query
parameter shows the query that is being run (in your Contents recipe): in this case,$[?(@.categories[0] in [Costa Rica Islands])]
. However, in your actual recipe, you use a parameter for the category name ([$$par0$$]
).In the result, the
itunes:summary
,itunes:episode
,guid
,link
and other fields are identified.
To see what your Category and Contents recipe returns for an XML feed:
- In the Android View, expand Gradle Scripts and double-click build.gradle (Module: app).
-
Locate the
debug
object and changetestCovergeEnabled
tofalse
, like this:debug { testCoverageEnabled false }
- Press Shift twice to bring up the Search Everywhere dialog box, and then type XmlParser.java to locate this file.
-
On line 190, where it says
if (map.size() > 1) {
, set a breakpoint by clicking once in the left gutter (just to the right of the "190" line number, in the empty column space).A red dot should appear, indicating the breakpoint at that point. When you run the app in debug mode, the code will stop at that breakpoint and show the contents of your Categories and Contents recipes.
-
Click the Debug 'app' button .
-
In the footer of the Android Studio window, click the Debug tab and then select the Debugger tab in the pane above to view the details. Let Gradle build the app with the debugger.
After the app builds, look for the Variables to populate (as shown in the screenshots in the upcoming steps). (If the variables never populate, make sure that you have
xml
as the value for theformat
property in your recipes. Otherwise, XmlParser.java never gets used.) -
To see the categories targeted by the
query
parameter, expand the map variable; then expand one of the items in the array (such as 0 > Value). You see all the categories returned.Note that the
query
parameter shows the query that is being run (in your Categories recipe) — in this case,//item/category/text()
.In the result, the categories are shown:
Technology
,Ham Radio
,Technology
, etc. - To see the contents targeted by the Contents recipe, click the Resume Program button (it appears to the left of the Debugger tab). The code then iterates to the next recipe (the Contents recipe) and returns the result.
-
Click map > value, and then expand one of the items in the array (such as 0). You see all the properties targeted for your Contents recipe.
Note that the
query
parameter shows the query that is being run (in your Contents recipe) — in this case,//item[./category='Technology']
. However, in your actual recipe, you use a parameter for the category name ([$$par0$$]
).In the result, the
itunes:summary
,itunes:episode
,guid
,link
, and other elements are identified. -
As desired, expand into each element to see the syntax that identifies text, attribute, or cdata properties.
Understanding what's selected is important for the
matchList
parameter, which doesn't use XPath but rather uses its own custom selection syntax, particularly with text, attributes, and CDATA sections. For details, see the matchList Parameter topic, specifically the XML tab – "Targeting Text," "Targeting Attributes," and "Targeting CDATA").Here's how this works in the debugger. For example, suppose your feed contains this element in the returned items:
<enclosure url="http://www.podtrac.com/pts/redirect.mp4/cdn.twit.tv/video/hn/hn0362/hn0362_h264m_1280x720_1872.mp4" length="870155893" type="video/mp4"/>
Fire App Builder looks through each element and applies a special syntax to parse out these values. For example:
Since the
enclosure
element has two attributes (length
andtype
), you can see what is selected for them. The#text
selector selects the element's text. Since theenclosure
tag doesn't have a value, only attributes, the#text
selector's value is""
(empty).The
#attributes
selector gets the attributes. Then#attributes/type
shows the value it returns (video/mp4
). And#attributes/length
shows its value:692813434
. And#attributes/url
shows its value:http://www.podtrac.com/pts/redirect.mp4/cdn....
When you configure the
matchList
parameter, you can more easily see how to identify those elements and attributes. For example, to map theurl
value to the Fire app BuildermUrl
property (Fire App Builder's content model) for thematchList
parameter, you would use this:"matchList" : [ ... enclosure/#attributes/url@mUrl ... ]
(The above code sample just shows one property mapping — the ellipses indicate omitted content.)
For the sample TWIT feed in Fire App Builder, however, the
enclosure
attribute (which relates to the RSS spec) isn't used. Instead, the MRSS propertymedia:content
is where theurl
is mapped.In the feed, this element looks as follows:
<media:content url="http://www.podtrac.com/pts/redirect.mp4/cdn.twit.tv/video/hn/hn0362/hn0362_h264m_1280x720_1872.mp4" fileSize="870155893" type="video/mp4" medium="video">
Fire App Builder indicates that the
media:content
element is selected. You can see its sub-elements (e.g.,media:title
,media:category
, etc.). The#attributes
selector shows the attributes formedia:content
. Its attributes includetype
,medium
,fileSize
, andurl
. Thus to target theurl
in thematchList
parameter for the Contents recipe, you would use this:"matchList": [ ... "media:content/#attributes/url@mUrl", ... ] }