Developer Console

Step 9: Configure Navigator

After you have set up your recipes, you need to configure the Fire App Builder UI to use this information. To do this, you will configure the globalRecipes object in the Navigator.json file with the categories and contents recipes you customized earlier. The Navigator.json file (located in app > assets) defines what type of user interface elements are in the app and how they communicate with each other, what activities are associated with the apps, the layouts, and more.

You will also configure the data loader recipes. The Data Loader Recipe file loads a media feed URL. Because the Data Loader Recipe can load only one media feed URL at a time, if you have multiple media feed URLs, you will have to create multiple Data Loader Recipe files, each time referencing the same category and contents recipes. This can be somewhat manual to set this up, but once set up, you won't need to touch it again.

Step 1: Remove the Hard-coded Category Example from globalRecipes

The default Navigator.json file contains a special hard-coded category with content processed by a different recipe. This section is highlighted in red below:

"globalRecipes": [
  {
    "categories": {
      "dataLoader": "recipes/LightCastDataLoaderRecipe1.json",
      "dynamicParser": "recipes/LightCastCategoriesRecipe.json"
    },
    "contents": {
      "dataLoader": "recipes/LightCastDataLoaderRecipe1.json",
      "dynamicParser": "recipes/LightCastContentsRecipe.json"
    }
  },
  {
    "categories": {
      "name": "Hardcoded Category Name"
    },
    "contents": {
      "dataLoader": "recipes/LightCastDataLoaderRecipe1.json",
      "dynamicParser": "recipes/LightCastAllContentsRecipe.json"
    }
  }
]

Unless you actually need this section to provide categories for your content, remove it from Navigator.json. (See Hard-Coding Your Categories below for more details.) Otherwise, your feed won't work. (Your app will say "Service Unavailable" when you run it, because Fire App Builder will attempt to process your feed URL using a recipe configured for the Lightcast elements.)

This hard-coded category section is included only to demonstrate the flexibility of Fire App Builder. If you don't have categories in your feed, or if you want to set off some content to be processed by a different recipe, it shows how you can do that. See Hard-coding your Categories for more details.

Step 2: Configure Navigator's Recipes

Fire App Builder is flexible enough to accommodate single media feeds or multiple media feeds. Most developers will just have a single media feed where all their media metadata and assets are listed. However, other developers might have three or four different feed URLs for different types of content. If so, Fire App Builder can also accommodate multiple feeds. See the tab corresponding to

Single Feed URL Configuration

Follow this process if you have just a single URL in your urlFile.json file (located in app > assets), like this:

{
  "urls": [
    "http://www.example.com/feed1.json"
  ]
}

If you just have a single feed URL, then configure Navigator.json as follows:

  1. Open the Navigator.json file (located in app > assets).
  2. Look for the globalRecipes object. By default, after removing the hard-coded categories section, it looks like this:

    "globalRecipes": [
      {
        "categories": {
          "dataLoader": "recipes/LightCastDataLoaderRecipe1.json",
          "dynamicParser": "recipes/LightCastCategoriesRecipe.json"
        },
        "contents": {
          "dataLoader": "recipes/LightCastDataLoaderRecipe1.json",
          "dynamicParser": "recipes/LightCastContentsRecipe.json"
        }
      }
    ]
    
  3. Update the file references here with your customized recipe file names (which you customized in an earlier step). For example, if you customized them with "AcmeMedia" instead of "LightHouse," this section would look like this:

    "globalRecipes": [
      {
        "categories": {
          "dataLoader": "recipes/AcmeMediaDataLoaderRecipe1.json",
          "dynamicParser": "recipes/AcmeMediaCategoriesRecipe.json"
        },
        "contents": {
          "dataLoader": "recipes/AcmeMediaDataLoaderRecipe1.json",
          "dynamicParser": "recipes/AcmeMediaContentsRecipe.json"
        }
      }
    ]
    
  4. Because the contents of the <project name>DataLoaderRecipe files differ based on whether you have an open feed or a token-based feed, follow the appropriate section below to configure the DataLoaderRecipe files.

    –> DataLoaderRecipe Configuration for Open Feeds:

    1. If you have an open-feed, open the <project name>DataLoaderRecipe1.json file (in app > assets > recipes) and ensure the content looks as follows (the default):

       {
         "task": "load_data",
         "url_generator": {
           "url_index": "0"
         }
       }
      

    –> DataLoaderRecipe Configuration for Token-based Feeds:

    1. If you have a token-based feed, open your <project name>DataLoaderRecipe1.json file (in app > assets > recipes) and replace the contents with the following:

      {
        "task" : "cache_data",
        "data_file_path" : "/",
        "url_generator" : {
            "base_url" : "http://yourcompany.com/mediafeed?id=$$token$$",
            "token_generation_url" : "http://yourcompany.com/url_to_generate_token"
        }
      }
      
    2. Configure the base_url and token_generation_url with the same values you used in BasicTokenBasedUrlGeneratorConfig.json (inside assets > configurations).

Multiple Feed URL Configuration

Follow this process if you have just a multiple URLs in your urlFile.json file (located in app > assets), like this:

{
  "urls": [
    "http://www.example.com/feed1.json",
    "http://www.example.com/feed2.json"
  ]
}

If you just have multiple feed URLs, then configure Navigator.json as follows:

  1. Open the Navigator.json file (located in app > assets).
  2. Look for the globalRecipes object. By default, after removing the hard-coded categories section, the object looks like this:

    "globalRecipes": [
      {
        "categories": {
          "dataLoader": "recipes/LightCastDataLoaderRecipe1.json",
          "dynamicParser": "recipes/LightCastCategoriesRecipe.json"
        },
        "contents": {
          "dataLoader": "recipes/LightCastDataLoaderRecipe1.json",
          "dynamicParser": "recipes/LightCastContentsRecipe.json"
        }
      }
    ]
    
  3. Update the file references here with your customized recipe file names (which you customized in an earlier step). For example, if you customized them with "AcmeMedia" instead of "LightHouse," this section would look like this:"

    "globalRecipes": [
      {
        "categories": {
          "dataLoader": "recipes/AcmeMediaDataLoaderRecipe1.json",
          "dynamicParser": "recipes/AcmeMediaCategoriesRecipe.json"
        },
        "contents": {
          "dataLoader": "recipes/AcmeMediaDataLoaderRecipe1.json",
          "dynamicParser": "recipes/AcmeMediaContentsRecipe.json"
        }
      }
    ]
    
  4. Make the pair of categories and contents objects match the number of media URLs in your URL file. For example, if you have 2 media URLs, you would need 2 pairs of categories and contents objects and a unique &ltproject name>DataLoaderRecipe for each pair.

    For example, suppose your urlFile.json file (which you configured in Load Your Media Feed) has two feed URLs:

    {
      "urls": [
        "http://www.example.com/feed1.json",
        "http://www.example.com/feed2.json"
      ]
    }
    

    As a result, your globalRecipes object in Navigator.json would look as follows, with two pairs of categories and contents objects, and a unique &ltproject name>DataLoaderRecipe file for each pair:

    "globalRecipes": [
        {
          "categories" : {
            "dataLoader" : "recipes/AcmeMediaDataLoaderRecipe1.json",
            "dynamicParser" : "recipes/AcmeMediaCategoriesRecipe.json"
          },
          "contents" : {
            "dataLoader" : "recipes/AcmeMediaDataLoaderRecipe1.json",
            "dynamicParser" : "recipes/AcmeMediaContentsRecipe.json"
          }
        },
        {
          "categories" : {
            "dataLoader" : "recipes/AcmeMediaDataLoaderRecipe2.json",
            "dynamicParser" : "recipes/AcmeMediaCategoriesRecipe.json"
          },
          "contents" : {
            "dataLoader" : "recipes/AcmeMediaDataLoaderRecipe2.json",
            "dynamicParser" : "recipes/AcmeMediaContentsRecipe.json"
          }
        }
    ]
    

    The file construction is rather manual here, but here's what's happening. Fire App Builder will first query for the categories, and then the contents. Fire App Builder can only get one URL at a time, so if your media feed consists of multiple URLs stored in the urlFile.json file (as is the case with the Fire App Builder sample app), you'll need to repeat the categories and contents objects for each URL.

  5. Based on the number of <project name>DataLoaderRecipe files in your globalRecipes above, go into the app > assets > recipes folder and create the needed <project name>DataLoaderRecipe files (you'll configure the file contents in the next step).

    For example, if you have 2 <project name>DataLoaderRecipes (AcmeMediaDataLoaderRecipe1.json and AcmeMediaDataLoaderRecipe2.json), go into app > assets > recipes and ensure you have the matching number of <project name>DataLoaderRecipe files (you'll configure the file contents in an upcoming step). AcmeMediaDataLoaderRecipe1.json already exists, so in this scenario, you would need only to create AcmeMediaDataLoaderRecipe2.json.

  6. Because the contents of the <project name>DataLoaderRecipe files differ based on whether you have an open feed or a token-based feed, follow the appropriate section below to configure the DataLoaderRecipe files.

    DataLoaderRecipe Configuration for Open Feeds

    1. If you have an open-feed, open the additional <project name>DataLoaderRecipes (in app > assets > recipes) and increment the url_index by 1 for each file. With an open feed, your <project name>DataLoaderRecipe1.json file's contents looks like this:

      {
        "task": "load_data",
        "url_generator": {
          "url_index": "0"
        }
      }
      

      This <project name>DataLoaderRecipe loads the data from the first line (http://www.example.com/feed1.json) listed in your urlFile.json:

      {
        "urls": [
          "http://www.example.com/feed1.json",
          "http://www.example.com/feed2.json"
        ]
      }
      

      <project name>DataLoaderRecipe2.json should increment the url_index by 1 to load data from the second line:

      {
        "task": "load_data",
        "url_generator": {
          "url_index": "1"
        }
      }
      

      This <project name>DataLoaderRecipe2.json file will load the second line (http://www.example.com/feed2.json) listed in your urlFile.json.

    DataLoaderRecipe Configuration for Token-based Feeds

    1. If you have a token-based feed, open each of your <project name>DataLoaderRecipe.json files (in app > assets > recipes) and replace the contents with the following:

      {
        "task" : "cache_data",
        "data_file_path" : "/",
        "url_generator" : {
            "base_url" : "http://yourcompany.com/mediafeed?id=$$token$$",
            "token_generation_url" : "http://yourcompany.com/url_to_generate_token"
        }
      }
      
    2. In each of your <project name>DataLoaderRecipe files, configure the base_url and token_generation_url with the same values you used in BasicTokenBasedUrlGeneratorConfig.json (inside assets > configurations). However, for each <project name>DataLoaderRecipe, load a different media feed URL, so that each base_url value is unique.

Hard-Coding Your Categories

If your feed doesn't include categories in the feed structure, you can hard-code a category name in Navigator.json and insert the entire media feed for that hard-coded category. Instead of loading your categories from the LightCastCategoriesRecipe.json file, you configure the categories inside the globalRecipes object in Navigator.json like this:

"globalRecipes": [
  {
    "categories" : {
      "name" : "Acme Category 1: Coyotes"
    },
    "contents": {
      "dataLoader" : "recipes/LightCastDataLoaderRecipe1.json",
      "dynamicParser" : "recipes/LightCastContentsRecipe.json"
    }
  },

  {
    "categories" : {
      "name" : "Acme Category 2: Roadrunner"
    },
    "contents": {
      "dataLoader" : "recipes/LightCastDataLoaderRecipe2.json",
      "dynamicParser" : "recipes/LightCastContentsRecipe.json"
    }
  }
]

Note that in this scenario, you load only the contents recipe, not the categories recipe (since you don't have categories in your feed). The contents object is loaded in the same way described in the previous section, with a separate DataLoaderRecipe file for each media URL in the URL file (as explained earlier).

Test Your App

To verify that your feed is configured correctly, build and run your app. Instead of the Lightcast videos, your video feed should load. The Fire App Builder logo will still appear on the Splash screen and the Home screen, but the videos should show your feed.

If your video feed does not load, troubleshoot the problem before continuing. If you can't resolve the issue, post the issue to the Fire TV forum.

Next Steps

Now that your feed is configured, it's time to start customizing the look and feel of your app (especially getting rid of the generic "Fire App Builder" logo). See Change the App Logo, Icon, and Splash Screen. This next topic is part of the Customize the Appearance map.


Last updated: Apr 06, 2017