Firebase for a Database, Writing and Updating a List

I am very excited to have been introduced to Firebase by Max of the previous post. Firebase is a service provided by Google and it does many things for developers. I am going to discuss the Realtime Database feature here, specifically writing and updating.

Why, you might ask, would I want to give the big G more access to my data? For me, it is a matter of ease of use. I want a database for an app I am creating for a personal project and it seems like the easiest and quickest way to spin that up. Perhaps I will go back and build a “real” back end at some point (for a variety of reasons), but for now, for testing the front end and the API calls, this will work very well and quickly.

Once on the site, you can sign in with your existing Google account and off you go. You can click “start a project” to begin. Name it, click continue, and your project is made. Now click on “database” under the develop menu toward the left side of the page. Then click on Realtime Database and you can begin in locked mode or in the test mode. If you begin in “locked,” you will want to go to the rules and change the read and write property values to true and then click “publish.” That will allow you, as you are spinning up your database, to, well, read and write. Authorization is absolutely included with the realtime database, but if you want to save dealing with that until later, you can definitely do so, as I am. Once you are ready for authentication, try reading this post, and it might help.

I decided to reach Firebase through my Vue app, and there are a couple of things that can make that easier. The link to your database endpoint will be at the top of your data page, and you could simply use that with Axios or Vue Resource and GET, POST, etc. To do so, watch section 15 of this tutorial.

If you would like to use Firebase methods in your application, though,
such as sorting and/ or filtering, you will need to do a few things. First, add it to your package.json —

npm install firebase --save

In your main.js file, you will need to

import './firebase'
Then you can make a firebase.js file to contain all of the configuration you need for using the database. On the firebase site, go to the project you are working on, click “project overview” on the top left, next to the house icon. You will be on a screen that says “Welcome to Firebase, Get started here.” Then click “Add Firebase to your web app.” Once you do that, a pop up window will appear with the keys and values that you will need for your configuration. Add this to your firebase.js file. To learn more about what all of these keys represent or alternative ways of configuring firebase, here are the firebase docs.
const app = firebase.initializeApp({
  apiKey: ,
  authDomain: ,
  databaseURL: ,
  projectId: ,
  storageBucket: ,
  messagingSenderId: 
});

Above that, you will need to import all of the firebase methods.

import * as firebase from "firebase";

Then, you can create a const to hold that database reference.

export const db = app.database();

Of course, you can call it whatever you want instead of “db.” You can also pass in a node in your database inside your parentheses as a string, for example:

export const recipeRef = app.database.ref('recipes');

You could also create the db const and then add the refs to that as specific consts as needed:

export const recipesRef = db.ref('recipes');

Then you can use the const in your .Vue file with any of the firebase methods. First you will need to import it.

import {recipesRef} from '../firebase'

or however you need to import it. . .

You can write to a list in the database with the push method. To find out about all of the methods for the database, look here. To simple add data,

recipesRef.push(this.recipe);
would work perfectly well when you are returning a recipe object in your data property.
You can also update an item in your database with the set method. With a list of data, each “row” is inside a key. So, to update that particular database entry, you can set a change on the child of the node by passing in the key. For example,
recipesRef.child(key).set(individualRecipe)

There is a lot more to be done in Firebase. To be continued!

 

Advertisements

Praise for Maximilian Schwarzmuller

Who? You might ask. . . For the last three weeks I have been tasked with learning VueJs as the people I work with vastly prefer that to React. I attempted to learn VueJs a little over a year ago, but at that point, it was a disaster for me. I’ve come in that year because in the meantime I have learned so much more about JavaScript and about programming in general. Now, learning VueJs has been a piece of cake. However, without this excellent Udemy course, I don’t think I would have been able to learn it so well and so quickly.

Max, https://www.academind.com/, teaches a variety of Udemy courses, but his focus is on JavaScript frameworks/ libraries. He has courses in Angular, React, and VueJs. He claims to like Vue the best. More on that another time. He also has some free courses on Bootstrap 4.0. More on that another time, too!

Max’s courses were recommended to me by my fellow BenefitMany developers. Because we have now all learned Vue from the same person, we are able to come at a problem from the same perspective. That allows me to easily understand what the code in their existing projects is doing without me even having to ask.

Max really keeps his code and programming up-to-date. He will add lectures or even change videos to make sure his content is current. He explains everything really well and clearly, of course, which is absolutely key. But, if you should have a question, he responds directly and quickly even though he has thousands and thousands of subscribers. My questions got responses in less than 8 hours! Also because there are so many subscribers, many questions have already been asked and answered.

The courses contain hours and hours of content, but it is all well-organized so one can easily jump into a particular subject and skip others that are less pertinent or interesting.  Going through the whole course will bring your skills way up as he also discusses the most popular libraries used with the code. For example, for the Vue course, he discusses Vue Router and two different Ajax libraries, Vue Resource and Axios. He also has a module on state management with Vuex. In addition, he has exercises and projects built in, and of course he goes over those coding challenges.

I have done many online tutorials, and so far, I have found his to be by far the best and most helpful. If the price seems steep on Udemy, try looking around for coupons. Usually they are available somewhere on the interwebs. Have fun learning some front end JavaScript!

Working Remotely

In my current position, I work remotely with a team of four other full-time employees. Three of us live in Pittsburgh (two are developers) and two live on the West Coast — if you consider Reno the West Coast. Anyway, our work flow is to meet (usually) once a day at 12:00 PM for “standup” using Zoom. That time is devoted to people sharing their Asana screens and talking about what they’ve done, what they are doing next, and if anything is blocking them. It is considered ideal for those meetings to take less than fifteen minutes. Once a week, on Wednesdays, we “meet” for an hour to review and plan the “sprint” for the next week. Most of that time seems to be devoted to the CEO and CTO arguing with each other. In between, we/ they use Slack for any quick questions or jump on a Google Hangout to go more into depth into an issue or concern.

The three other developers on the team are fairly experienced, and working remotely is a great way for them to have flexible schedules. Also, they are coming from another company where they worked together and in order for the three of them to continue to work together, they have to work remotely, with two of them being of an age and situation where picking up and moving is out of the question. After I accepted this position, I was offered a full-time position at a local company that would be about a 45 minute average drive from my house. The amount of commitment to that position, which frankly wasn’t my ideal in terms of lack of flexibility, made a remote job sound much more appealing.

There are some downsides to working remotely, though. The biggest downside for me is because I am a bit of a newbie. I have sometimes gotten blocked on very simple questions and tasks and spent a lot of time trying to figure things out.

Being blocked has made my billable hours drop, unfortunately. We use Harvest to keep track of our time spent. Ideally, almost all of that time is on tasks for the company that hired us to build the site and are detailed in tickets in Asana which are created directly from the bid. I billed for two hours last week — two points, two tickets — but clocked 48 hours in Harvest on “education.” Uh oh. I included notes for each education task. That “education” was me trying things and looking things up and trying things and looking things up again in order to make the code do what it was supposed to do. I detailed and clocked all the hours spent because I wanted the others to know that I was working hard and wasn’t blowing off the work. My choice to only bill for two hours comes from direction from the CTO about how much time the task should have taken.

A lot of my slowness has to do with my newness to certain languages and uses of the languages. But another major cause of slowness is my lack of overall knowledge relating to certain little tricks or syntax. Sometimes I happen on answers to those questions serendipitously and quickly. More often though, there have been so many times in my brief career as a  developer when a more experienced developer has told me something in a short sentence that would have saved me literally hours of time. I don’t know how others deal with these problems.

Two examples from the past two days might illustrate what I am talking about. In one case, we are now using Redux and Thunk in a React front end for a web app. I have not used either before and was a little overwhelmed with the confusing practices. I followed a tutorial, but it did not use Thunk, so that particular file — the action creator that uses Thunk — was fairly confusing to me. The stupidest little thing was preventing me from really understanding what was happening (and thus being able to make modifications to do what I needed to do), and it has to do with ES6 syntax. When you are writing an anonymous function, you can eliminate the parentheses if only one argument is passed in. Duh! I don’t know how I managed to miss that but I will never forget it now.

So when I saw this function:

export function importDelete(id) {
  return dispatch => {
    deleteImport(id)
  .then(response => {
    dispatch(importDeleteAction(response.data.import.id))
      }).catch(err => console.warn(`import deletion failed: ${err}`))
    }
}

All I saw was gobbledy gook at the top. I could not figure out why two dispatches were being called!? What was the first one even doing? Now I understand and can write this function passing two arguments to the anonymous function:

export function exportCreate() {
  return (dispatch, getState) => {
    const state = getState()
    exportPolicies(state.startDate, state.endDate)
  .then(postResponse => {
    const response = postResponse.response
    dispatch(exportCreateAction(response))
     }).catch(err => console.warn(`export create failed: ${err}`))
  }
}

The other stupid thing that threw me off that someone corrected with one word has to do with styling with Bootstrap. Styling things is absolutely not my forte. A UI element I was making that was meant to be an input group where someone could put in a start date and end date and then hit a button to send an API call just was not lining up and was looking very ugly. I tried using inspect and looking at padding, margins, alignment, justification, you name it. The next day, after giving up, I asked for help. The senior front end developer suggested just putting the elements inside a row. Ta da! Now it all lined up with the content that followed and looked so much better. How could I forget about rows?

Because I feel so incompetent (imposter syndrome anyone?) I am reluctant to ask what seem to be stupid questions.  Not working side by side with people and developing a level of comfort and a rapport with them has made it very hard for an old, new developer to learn and grow at a reasonable rate.

With some perspective I can now suggest two things: try to get to know your coworkers on a more personal level, and try to take introductory courses if possible. If I had spent 12 hours on an intro to ES6 course and/ or an intro to Bootstrap course, I would probably not have wasted all of that time and would be billing more hours even as we speak!

Working Hard vs. Working Smart

Should I be grateful to be praised for working hard?

My mentor yesterday again stressed the importance of TDD. You might wonder how these two sentences are related. I will get to that; I promise.

Why TDD? It can help you design your code in a smart way. If you need to bring in all sorts of stubs and mocks of other functions and objects to run a test, then you are probably not creating code the right way; it is too modular. He says the test is the first user of the code, and says that it allows you to see what is involved in that code usage. I have not really been using it. He was saying this in reference to code that I wrote and how awful it was.

Of course I have not been using TDD. Maybe I’ll start. We will see. I haven’t because I usually spend so long on tests. Yesterday I spent about four and a half hours trying to get one test to pass. That has been a recent pattern for me, spending hours and hours trying to get tests to pass.

In the current project we are working on, we are using Rails and Rspec in the back end. Like with most things in code, I am trying to learn by copying existing examples in the code base and using Google and/ or documentation to figure out what to do. As “everyone” says, once you learn the coding concepts, it is just syntax. I could not disagree more. Because of that, none of my superior or colleagues or whatever ever take the time to teach syntax. I am expected to figure it all out myself.

Luckily, with Rspec, there are plenty of SO opinions and ideas. Rails has been used for years and years, and Rspec along with it. The docs from Rspec itself are not at all helpful though. I am always lead to the Relish site and that was last updated two years ago and all it does is confuse me.

Here is one example of the trouble I had and what I eventually discovered.

I created a get endpoint in a controller that is where users will go to when they get an email to activate their account (or update their email). This endpoint does not have any of it’s own resources. However, it does modify the user resource by setting an activated_at in one action and resetting the email in a verify action and then the new version of the user is returned in the JSON. In the controller test, I was able to copy other patterns in existing tests to check for valid JSON, and that passed perfectly.

Then, with the CTO of the project who has been working in Rails for ten years, said we need to check if the user was updated. He is also serving as an instructor for me, mostly in the Rails part of the project. Unfortunately, a stupid mistake on my part and lack of attention on his part, led to a test that passed because it was not testing the right thing. I accidentally checked if the updated_at property on User was not nil instead of the activated_at. The test passed and the CTO hung up.

Here was the test:

context 'should respond by returning a user and updated_at in json if token is found' do
  subject { get :activate, params: @valid_params }
    it { expect(json.keys).to eq(['user']) }
    it { expect(json['user']['activatedAt']).to_not be_nil }
    it { expect(@test_user.updated_at).to_not be_nil }
end

It was only later I realized the mistake, and when I changed the test to check the activated_at property, I could not get anywhere after flailing around for quite some time. Of course I tried to rewrite the code in the the controller, thinking perhaps it was the actual code that was causing the problem. I really doubted it though. Then, when I was asked about the status of the pull request by the other two people on the project, I explained the problem I was having. The tests were not showing that the user was being updated. One suggested I try to reload the instance of the user that I was using in the test. @test_user.reload.

The reload did not work, but it lead me toward an answer. I got the response from the test that it could not perform reload on nil. Aha. This was a clue. Why was the @test_user nil? First I tried a different way to create a user instead of using the test user created in a helper file. No luck. Imagine hours passing. Of course it takes about five minutes to run each of the the tests, but a lot of that time is me not making decisions that make sense. binding.pry was not a super help because it showed that there was a @test_user. It was the old version of the @test_user, though, and didn’t show any updates.

Eventually, I realized through some random Googling and one of those ah-ha moments that the problem was how I was writing the test. I had been using the language of the test without understanding at all what it was doing. By copying and pasting and not really investigating, of course it would take me hours and hours to write a passing test. Even though knew from the start that the “it” in the test related to the “subject,”  I didn’t really think too hard about that subject and what it was or wasn’t doing.  Here is the relish docs explanation of “subject”:

“Use subject in the group scope to explicitly define the value that is
returned by the subject method in the example scope.

Note that while the examples below demonstrate how subject can be used as a
user-facing concept, we recommend that you reserve it for support of custom
matchers and/or extension libraries that hide its use from examples.”

I still don’t understand what that means. Do you? Eventually, what I landed on is that the subject should not have been the get request. The subject should have been the user.

Now the test looks like this:

context "should update the user object's activated at to the current time" do
  subject(:active_user) { User.find_by(perishable_token: @user.perishable_token)}
    before { get :activate, params: @valid_params }
    it { expect(active_user.activated_at).to_not be_nil }
end

And it passed!

You’d think I’d have learned. Then yesterday I spent about 4.5 hours not understanding why a test wasn’t passing without thinking about what exactly the test was testing even though the words, “it doesn’t test side effects” should have made me realize it! I kept modifying the code and the tests still didn’t pass.

Perhaps now you  realize why I have not been practicing TDD. If I have so much trouble writing tests, how can I possibly ever use those to help write code? I have not been able to work smart enough to work smartly. I have no solutions. Only mistakes. If there were a good way to learn more about how these tests work, I guess that would be a good start.

Lessons from Working on a Small Team

Cargo Cult Programing

Since October I have had the great pleasure of working with a brilliant man who has served as a mentor in both programming and working in the development world. Yesterday he told me a little about what he thinks is “cargo culting.” I had never heard the term, but after having one explanation and then reading about it, I agree with him that it’s such a regular phenomenon, there really doesn’t seem to be any reason to have a specific term for it.

As was told to me, but turns out not actually to be true, cargo culting, in case you are not familiar with the term, refers to some alleged behavior discovered by an alleged anthropologist among some Pacific Islanders during World War II.  Planes would crash sometimes and crates of supplies would wash up on shore of these islands. Imagine the delight of these islanders to find boxes full of bad tasting chocolate and cartons of cigarettes (or whatever there was). So, in response, the islanders would take to performing repeated rituals that related to what they were doing when the crates washed ashore. So, if they had been talking to a certain person or had eaten something particular, or had performed a certain task, they would then do that thing as a ritual in the hope that it would send more delightful supplies to their shore.

Cargo cult behavior, according to Wikipedia, anyway, is a lot more complex then that. But the point is, to quote Wikipedia, the term “cargo cult” has been used metaphorically to describe an attempt to recreate successful outcomes by replicating circumstances associated with those outcomes. It is particularly used in the computing world to describe inclusion of behavior for no real reason.

I thought about this term last night when we had our mandatory meeting with the Rabbi before my son’s upcoming Bar Mitzvah. She talked about why old Torah scrolls that have holes in them and can be no longer used are still kept in the arc (harom a kodesh sp?). She said it’s because when Moses went up to get the ten commandments from God and smashed the pieces, the new ten commandment tablets and the old, smashed, broken tablet of commandments were both included in the ark. That makes you realize that basically all of human behavior is some form of cargo culting.

So, back to programming. Now I am working with a few other experienced programmers, which is a great opportunity for me. But, there is a lot of tension on the team. On the one hand, there are the people who repeat over and over, “this is how we did it at company x for years and it always worked out well,” and on the other hand you have my mentor (see beginning of this post) who is struggling to be productive in an environment that doesn’t make sense to him. And then there is the code base, copied over from projects done on the past. And there is me, caught in the middle.

It has definitely been a learning experience working on an experienced software development team for the first time.

Update: The company fired my friend as they felt they just could not work with him.

Dealing With XML

Until recently, I have only been dealing with API data that is in JSON (JavaScript Object Notation – pronounced like the name Jason) format. JSON looks like

[{"replayEventTypes[{"id":5,"name":"movies","displayName":"Watch"}],
"id":70,
"title":"Notification Testing I",
"date":"2017-05 26T00:00:00",
"startTime":"08:20",
"endTime":"20:00",
"description":"Testing to see if notifications work on IOS",
"extendedDescription":null,
"location":"Not Important",
"image":null}

It could not be easier to access various levels of the object by using the dot notation. To get the values of the properties inside your html, you just reference the property on the object by object-name.property. So, for example, <h1>event.endTime</h1>.

Recently, I had to process an XML API, and, not surprisingly access to the various properties is different than with JSON. XML stands for eXtensible Markup Language. It is similar to HTML except different. Its purpose is to transport data over the web (as opposed to being used for display as HTML is). I was accessing the API in order to allow someone doing data entry to look up an Arcade Game and populate fields related to that game with the values of properties from that API.

Here’s what a “real” example of XML looks like:

<Game> 
<id>2</id>
<GameTitle>Crysis</GameTitle> 
<Platform>PC</Platform>
<ReleaseDate>11/13/2007</ReleaseDate> 
<Overview>From the makers of Far Cry, Crysis offers FPS fans the best-looking, most highly-evolving gameplay, requiring the player to use adaptive tactics and total customization of weapons and armor to survive in dynamic, hostile environments including Zero-G. Earth, 2019. </Overview>
<ESRB>M - Mature</ESRB> <Genres><genre>Shooter</genre></Genres>
<Players>4+</Players>
<Co-op>No</Co-op>

Here is my function as written in the script section of a “create” View file in .NET/ MVC project.

 function fill_form(id) {
            $('#games-by-id').html('');
            $.ajax({
                url: 'http://cors-anywhere.herokuapp.com/http://thegamesdb.net/api/GetGame.php?id=' + id,
                type: 'GET',
                dataType: 'xml',
                success: function (data) {
                    var gameTitle = $(data).find('GameTitle').text(),
                        overview = $(data).find('Overview').text(),
                        releaseDate = $(data).find('ReleaseDate').text(),
                        developer = $(data).find('Developer').text(),
                        genre = $(data).find('genre').text(),
                        players = $(data).find('Players').text();
                    var tempReleaseDate = new Date(releaseDate);
                    var releaseYear = tempReleaseDate.getFullYear();
                    $('#GameTitle').val(gameTitle);
                    $('#Overview').val(overview);
                    $('#ReleaseDate').val(releaseYear);
                    $('#Developer').val(developer);
                    $('#Genre').val(genre);
                    $('#Players').val(players);
                },
                error: function (error) {
                    console.log(error);
                }
            })
        }

So, as you can see, using JQuery and an AJAX request, you need to pass in XML as the data type and pass that data or xml or whatever into your callback function. Then you need to “find” each XML tag in the “data” (or xml or whatever), assign it a variable, and then put that variable into the HTML, which I did using the ids on the attributes.

To load what I would consider an array of XML objects, you can simply look at “each” of them. Good old jQuery. If you don’t have one of the new libraries or frameworks, it sure beats Vanilla JavaScript. For example,

 success: function (data) {
                    $('Game', data).each(function () {
                        var id = $(this).find('id').text(),
                         gameTitle = $(this).find('GameTitle').text(),
                         releaseDate = $(this).find('ReleaseDate').text(),
                         platform = $(this).find('Platform').text();
                        $('#games-by-id').append('<li class="list-group-item"
id="game' + id + '"><span id="catspan' + id + '"></span>' 
+ gameTitle + '</br>' + releaseDate + ' ' + platform + '</li>');
                        $('#game' + id).click(function () { fill_form(id); });
                    })
                }, 

You may have also noticed that I need to make a CORS request here. I will have to address that in another blog post once I figure out how to run my own proxy server.

I read a lot of different posts with lots of different ways to access XML, including from the JQuery documentation, but this is the way that is working for me.

Refactored Push Notifications

In my last post, I described how we set up a local React Native Push Notification to run at a scheduled time. The push notification was configured on the App State Change — background to active and vice versa. By sending an id (on Android) the notification was configured once and sent at the correct time, but only if the user had changed the state of the App. In iOS, there is no ID parameter (as such — I will get to that later), so if a user changed the state (opened the app, put the app in the background) multiple times, the push notification would fire multiple times.

I got to thinking about it and decided on a better way to configure the notification. I was hung up on the idea of an event listener. In React, you really have to either have an event listener or a lifecycle event to change/ update/ set the state. I was pretty sure we did not want to configure the notifications with a button push. Except, we actually did.

The push notifications are for events that are favorited by the users. So, I did a Homer forehead slap (“doh”) and realized we could just configure the notifications on the button push to add the event to the favorites array. And, even better, I realized if someone unfavorited the event, we could now remove that notification.

Cray then figured out that for iOS, we can send in a userInfo object and send an id in as a property on that object; that way there is an id to add and remove on iOS for the push notification. And, we can still use the id string property for Android.

Now the push controller looks like this:

import React, {Component} from 'react';
import PushNotification from 'react-native-push-notification';

export default class PushController extends Component {
    ComponentDidMount() {
      PushNotification.configure({
      onNotification: function(notification) {
         console.log('NOTIFICATION:', notification);
         console.log('User Info:', userInfo);
      }
    });
  }

    render() {
      return null;
  }
}

In a separate file, we have this function call:


handleFavoriteButtonPress(item){

    if (item.isFavorite){

            this.props.removeFavorite(item.id);
          //  Alert.alert('Item has been removed from your schedule');
          let id = (item.id).toString();
          PushNotification.cancelLocalNotifications({
            id: id, //removes local notification when item has been unfavorited
          });
        }
          
          else {
            this.props.addFavorite(item.id);
            if(this.props.favorites.length =10 ? "-"+(favoriteDate.getMonth()+1) : "-0"+(favoriteDate.getMonth()+1);
            let favoriteDay  = (favoriteDate.getDate()+1) >=10 ? "-"+(favoriteDate.getDate()+1) : "-0"+(favoriteDate.getDate()+1);
            let fifteenMinutesUntil = new Date ( favoriteDate.getFullYear()+favoriteMonth+favoriteDay+"T"+item.startTime+ "-"+"03:45");
          
            let id = (item.id).toString(); 
            if( fifteenMinutesUntil >= Date.now()){
              PushNotification.localNotificationSchedule({
              id: id, //for Android
              userInfo: {id: id}, //for iOS
              message: item.title + ' will begin in 15 minutes',
              date: new Date(fifteenMinutesUntil),
           });} 
          }
    }

One thing you should know is that even to send local push notifications, you will need to get the permission from Apple to do so.

As quoted from their docs

For a provider to communicate with APNs, it must employ a valid authentication key certificate (for token-based connection trust) or SSL certificate (for certificate-based connection trust). You obtain either of these certificates from your online developer account, as explained in “Configure push notifications” in Xcode Help. To choose between the two certificate types, read Provider-to-APNs Connection Trust. Whichever certificate type you choose, provider connection trust is prerequisite to a provider sending push notification requests to APNs.

Hope this was helpful.

React Native Push Notifications

See Refactored Push Notifications to get the update. Hey, I said I make mistakes, right?

The most recent feature we have been charged to add to the Replay FX application for the Replay FX convention this summer is push notifications. In the app, convention goers are able to save favorite events locally so they can have their own tailored schedule. We wanted a push notification for them that would let them know when an event they had ‘favorited’ was coming up in fifteen minutes.

We chose the package “react-native-push-notification,” so that we could configure local notifications on both IOS and Android. I watched this helpful video to get started. There are several files to change in Android, and you can easily follow along with the video or use the docs. I did not work on the IOS side, but my colleague Cray configured that in XCode. He had used something similar when he did a code test building a chatbot.

So, we started with a separate file that has State. It has to have “state” because it needs to be updated based on time and the current app state. Cray first had a notification sending based on intervals just as in the video. To render the notification, he imported the component to the item piece of our list view and included it inside the view like this:

Screen Shot 2017-04-28 at 1.52.13 PM

Now that he had set up where and how the PushController component renders, we needed to fine tune the PushController file. Of course, import the file at the top.
import PushNotification from 'react-native-push-notification';


The following code in some kind of form needs to exist to configure the push notifications. Of course, you do not need to console.log but can do all kinds of other things with the notification object upon callback.

componentDidMount() {
  AppState.addEventListener('change', this.backgroundNotification);
    PushNotification.configure({
      onNotification: function(notification) {
         console.log('NOTIFICATION:', notification);         
      },
    });

I wanted to be able to write the code without the event listener because I feel like it just causes trouble, but the package to configure the push notifications does not seem to function without it. The only argument that I could find to pass into the event listener was “change” which is a little annoying. What if the user of the phone does not “change” anything? For example, they could have the app open, favorite an event, and not close the app or put it in the background. In that case, the notification will never fire.

I created a second listener to add to this function to render when we have an in-app notification. And, of course, we remove the listener on “componentWillUnmount.”

The functions are called on “change” — opening the app or putting the app into the background and when the function is called we have a bunch of “if” statements. The code that follows is the function that is for the background notifications. I had to create a different function to run if the appState is “active.” I tried to do an “or/||” statement and just have one function, but it did not work. The app would just crash with the “or.”


backgroundNotification(appState) {
      if (appState=='background') {
      if (this.props.item.isFavorite) {
        let favoriteDate = new Date(this.props.item.date);
        let id = (this.props.item.id).toString();

The above code, gets the date of the favorited items so that we can create a variable that has “state” to represent the date and time of 15 minutes before the event.

The code to create that variable is ugly, but it works, and I don’t know of a better way. Dates and times are very tricky in JavaScript.


this.setState({fifteenMinutesUntil: new Date(
          favoriteDate.getFullYear() +"-0"+ (favoriteDate.getMonth()+1)+"-"+(favoriteDate.getDate()+1)+"T"+this.props.item.startTime+ "-"+"03:45"
          )});

We needed to have a Platform.OS “if” statement to render the date correctly In Android, I needed to add +1 to the getDate(). For IOS, the +1 only needs to be added to the getMonth(), which is also true in Android.

Once we have that variable, we can create a notification to fire at the appropriate time. We had some trouble with notifications firing immediately if the event time had passed, so Cray created the “if” statement at the beginning of the code below to go along with the configuration of the notification.

We had to pass the id or the PushNotification.configure would create a completely new notification object each time there was an app change. In that situation, when I did not pass a specific id, and I changed the state of the app, many, many notifications would fire. By passing the id — by the way, it has to be a string — we only create one notification object and only one notification fires.

The way the notification works “under the hood” is by adding .getTime() to the date and returning the milliseconds. The getTime() function did not work if we did not create a new date here. As it is, the notification fires once at the date and time passed to date.

One little problem that I have not figured out is that when I click on the notification in the emulator it automatically opens the app. I don’t know if there will be a dismiss “x” on the screen of people with real phones. I hope so.


if(this.state.fifteenMinutesUntil >= Date.now()){
           PushNotification.localNotificationSchedule({	
            id: id,	      
            message: this.props.item.title + ' will begin in 15 minutes',
            date: new Date(this.state.fifteenMinutesUntil), 

It took me several days and lots of console.logging but it works pretty well now on the simulators. I can’t wait to see how it builds this evening in our beta. There was very little help out there — only the one video, no StackOverflows, and nothing in the docs — to work for our specific situation. I hope that this post helps you figure out local scheduled push notifications.

And, I figured it out some more important things and rewrote the code after this. See Refactored Push Notifications to get the update. Learning from mistakes, just as promised.

React Native EMFILE Error

So yesterday I was preparing to add a feature to the mobile app we created for the Replay FX convention. We need to add local push notifications. There have been two of us working on this app since our Academy PGH bootcamp ended back in December. To make things simple, my coworker, Cray, has been developing and testing using an iPhone simulator and XCode and I have been using an Android simulator and Android Studio, even though we both have Macs and iPhones.

He had a chance to get back to coding for the first time after his first child was born two weeks ago and got a basic version up and running on his ios simulator. Using git I merged his code into mine and then did a “yarn install” to get the package we are using — “react-native-push-notifications.” I am giving you all of this background because I am still not sure what caused the problem I ended up having, so I am hoping this exposition might solve the mystery later, although it could be a red herring. At that point, a message in my terminal indicated that I should update my version of Yarn using the command they gave, which I did. Perhaps because I installed a new Yarn version I caused some change in one of my dependencies which caused things to break later? I don’t know. . .

At first, the app crashed because my coworker had added new Android “drawables” for our splash screen into a file (called “ApeGeneratedAssets”) outside of the android file. It was so great that he created that splash screen and added those android versions, but they were in the wrong place as far as I could tell. I had not set the layout file to read from there (plus the file names were all a bit wacky). He used Ape Tools to generate the different versions of the image, which seems like a handy method. So I moved those over into the “res” file and renamed them. I’m not sure if this will come back to haunt me later.

Anyway. . . the message which appeared all in glorious red on the emulator was “Could not get BatchedBridge, make sure your bundle is packaged correctly.” In my terminal, the message was “Error watching file for changes: EMFILE {“code”:”EMFILE”,”errno”:”EMFILE”,”syscall”:”Error watching file for changes:”,”filename”:null}”. In Android Studio, the only thing I could find in debugging the project was a seemingly random message from the android/app/build.gradle related to this line right at the top: “import com.android.build.OutputFile” saying “cannot resolve symbol build.”

Googling that message lead me here. So, first, I tried to clear the cache in Android Studio by going to File > Invalidate Caches / Restart as explained in the Stack Overflow post. That did not change a thing.

So, next, after Googling about the BatchedBridge and finding many answers to run “react-native start” (in the terminal) instead of my usual “react-native run-android” I did that, and it changed absolutely nothing. I next Googled about the EMFILE and got this explanation from the React Native GitHub “issues” page. It is explained that the build fails because there is a limit (in the new OS version of Sierra) in the number of files that can be opened. This made sense as a cause of the problem to me as I had added an additional Node module plus all of the big image files. So, I ran “launchctl limit maxfile” and sure enough I found my limit was 256. I ran “sudo launchctl limit maxfiles 2048 unlimited” to change that file limit. I followed the next commands to uninstall the react-native cli and reinstall it and then to update brew and install watchman. And then, tada! It worked. Only 2 hours and 15 minutes later. Now I just have to write the code to make the Push Notifications do what they are supposed to.

CSS and Caching

My original intent for keeping a blog was to help me remember solutions to problems in programming/ coding that I encountered. Because I am learning so much every day, I have had the problem in the past where I have figured out how to do something and then the next time — maybe a week later, or a month later — when that problem came up again, I had forgotten my original solution. I wanted to keep a blog so that I would have a place to record that solution for myself and for anyone who might need it. I wanted to write brief, fact and experience-based methods for solving problems.

So, despite the type of entries I have as my first two posts, what follows is the type of blog post I actually had in mind.

Yesterday I was working on a PC using Visual Studio 2015 to modify a version of Trello (I called it Trillo – clever, eh?) I created during my bootcamp to help me learn dotnet’s MVC. I decided that I wanted to change the colors of my todo cards, so I changed the colors in the Site.css file. But, to my surprise and frustration, every time I tried to view those changes by hitting “play” in VS (using Chrome), they just did not take. I tried reloading, closing and opening Visual Studio, “playing” by using the “Build Solution” menu, checking the save path, saving the .css in a different way (without changing its name), changing the way the .css was being loaded — by including it specifically by name — and nothing worked. When I looked in the Inspector, I had noticed that the source file was an old version of the site.css and it had a yellow triangle with an exclamation point in it which when hovered over said that “changes to the source file were not kept” or something like that.

So, as I should have done an hour previous, I Googled. I have had trouble Googling for MVC solutions in the past because I am dealing with a specific version of MVC, ASP.net, Entity Framework, and Visual Studio, and it is hard to find the precise combination necessary. In this case, there were no shortage of answers. It seems to be a common problem for sure. Chrome is caching the .css files. The easiest solution I found was to open the Inspector, open the source file for the .css, and while it is open, hit CTRL/ F5. This worked immediately to reload the .css file so that the current file was reflected in my local version. Then, when I made additional changes to the .css, I had to do the same procedure.

Looking at the solution in Stack Overflow,  I came across another helpful tip. In the Chrome Inspector click on the three dots menu (on the top right) to open up the Developer Tools. Then click on “Settings.” In there, check the box: “Disable cache (while DevTools is open).” Other solutions have you changing your code to always have you reload the cache. That does not seem that it would be helpful once your site is live, but you could use it while you are developing. If neither of those fixes work for you, please see the original Stack Overflow question I found. There were many, many solutions offered. The two above helped me, but you never know what might help you. By the way, last night I had a dream (nightmare?) that Stack Overflow had been attacked too many times and it had to be taken down. What a relief when I woke up from that one. . .