Building an enterprise mobile app using React Native and Realtime - part 2/3

  • Nov 17, 2015
  • React Native, Code Hosting, Cloud Storage

The Application

In this section we’ll guide you through some details of the React Native version of the Realtime News app (don't forget to check the GitHub repository for the source code at https://github.com/realtime-framework/RCTRealtimeNews), namely how to authenticate a user, use the authenticated token to get the contents from the Cloud Storage backend, content presentation and also the process of receiving a push notification.

User authentication

When the app is launched the users will see the login view, where they should enter their valid credentials according the contents of the Users table. You should use the CMS backoffice to manage your app users.

When the user taps the login button a REST POST is sent to the authenticate function stored in the previous steps in the Realtime Code Hosting backend.

Login screen on iOS
Login screen on Android

Below you’ll find the React Native code to call the authenticate endpoint and retrieve the authenticated token.

if (!this.state.username) {
      AlertDialog.show('Username empty');
    }
    else if(!this.state.password){
      AlertDialog.show('Password empty');
    }
    else{
      this.refs.loadingControl.startLoading();   
      fetch(sprintf(Config.CODEHOSTING_STORAGE_URL, Config.APPKEY, this.state.username,this.state.password, Config.ROLE), {method: 'post', 
        headers: {'Accept': 'application/json','Content-Type': 'application/json'}, body:''})
      .then((response) => response.text())
      .then((responseText) => {
        var response = JSON.parse(responseText);
        if(response.Error){
          AlertDialog.show('An error has occured: '+response.Error);
        }
        else{
          console.log(responseText);
          var token = JSON.parse(responseText)["token"];
          localStorage._onValueChange(token);
          this.props.login();          
        }
      })
      .catch((error) => {
        AlertDialog.show('An error has occured: '+ error.message);
      })
      .finally(() => {
        this.refs.loadingControl.stopLoading();
      });
    }    
							

Loading contents from Cloud Storage

To show the contents on both platforms (iOS & Android) we used a drawer menu for navigation. For iOS we also have the typical tab bar:

  • Recent, in this section all contents are presented in creation date descending order;
  • Blog, this section presents the contents belonging to the blog type;
  • o White papers, this sections presents the contents belonging to the white papers type.

Newslist screen on iOS
Newslist screen on Android

The React Native code below shows the data retrieval from Cloud Storage using the tableRef getItems method.

getContentsByMonthYearInit: function(currentDate){    
    var tabref = RCTRealtimeCloudStorage.table(Config.TABLE_CONTENTS);
    var itemsMaxLimit = Config.ITEMS_MAX - newsList.length;
    tabref.limit(itemsMaxLimit);
    tabref.equalsString(Config.ITEM_PROPERTY_MONTHYEAR, currentDate).desc().getItems(function(receivedData) {
      console.log(receivedData);
      if(receivedData){
        var itemCached = StorageController.prototype.checkIsCached(receivedData.Timestamp);
        if(itemCached){
          itemCached.isCached = true;
          newsList.push(itemCached);
        }
        else{
          newsList.push(receivedData);
        }
      }
      else{
        localStorage._getFirstContentMonthYear(StorageController.prototype.checkLimits,currentDate);        
      }
    },
    function(data){
      console.log('error:' + JSON.stringify(data));
    });
  }							

Content filtering

The hamburguer button menu

The options menu allows the user to filter the contents using the pre-defined tags.

Filter menu on iOS
Filter menu on Android

Content presentation

News detail

When you click on an item of the newslist, the detail of the news is loaded through a webview component. At the moment of this post writing React Native doesn't have support for WebView on Android so we used this component recommended by the React Native platform itself.

News detail on iOS
News detail on Android

Mobile Push Notifications

When there is a new content available, the Code Hosting script attached to the trigger after put on the Contents table is fired and the mobile app receives a push notification. This happens because the application is subscribing the channel notifications using the Realtime Messaging Push Notifications. When the user taps the notification alert the application is launched and the user is redirected to the new content detail view.

Below is the React Native code for handling the push notification on both platforms:

//index.ios.js
...
onNotification: function(data)
  { 
    var jsonData = JSON.stringify(data);
    console.log("Received notification: " + jsonData);  
    var response = JSON.parse(jsonData);
    console.log("Response", response);
    var url = response["URL"];
    console.log("URL: " + url);
    var body = response["Body"];
    console.log("Body: " + body);
    if(this.refs.nav){
      EventEmitter.emit(Config.STORAGE_REFRESH, { itemUpdated: response });
      this.refs.nav.push({
        component: WebViewScreen,
        passProps: { url: url, body: body }
      });
    }
  },
  ...


//index.android.js
...
onNotification: function(data)
  { 
    var jsonData = JSON.stringify(data);
    console.log("Received notification: " + jsonData);  
    var response = JSON.parse(jsonData).payload;
    console.log("Response", response);
    var url = response["URL"];
    console.log("URL: " + url);
    var body = response["Body"];
    console.log("Body: " + body);
    if(this.refs.nav){
      EventEmitter.emit(Config.STORAGE_REFRESH, { itemUpdated: response });
      this.refs.nav.push({ title: 'webview', url: url, body: body });
    }
  },
  ...
							

GitHub repository


In the next section we’ll have a look at the bootstrap CMS backoffice, the website you’ll use to manage your contents, tags and users.

Click here to proceed to the backoffice tutorial

If you find this interesting please share: