Skip to main content

Helpouts, Meetups, and the Mirror-Quickstart

Earlier this week I had my introductory interview with the Helpouts crew to verify the skills that I claim to have and to get an overall feel for how the system works and what to expect from a Helpout. I think the system will be very useful and I look forward to both providing Helpouts and utilizing them to learn new things. I asked if Helpouts would be able to utilize Glass, and at current it does not, but Helpouts hasn't launched yet, so anything can change. I received confirmation that my Helpouts listing has been approved yesterday and that it will be one of the first available when Helpouts goes live. They also said that they would be sending me a few invitation codes for friends and family to practice prior to the launch date, so if any one is interested in helping me practice or if you need any Tech assistance, let me know.

Thursday I attended a meetup co-hosted by +Antonio Zugaldia of Silica Labs and +GDG Washington DC. It was informative and interesting. Antonio created a sample app that demonstrates many aspects of the Mirror API and many best practices for developing Glassware. You can find the code over on his Github. I haven't had a chance to pull it down and begin playing with it yet, but it is definitely on my TODO list. 

In the meantime, I've been struggling to get the Mirror-Quickstart-Go up and running. A few months back I was able to get it running on an appengine instance without any trouble at all. Recently though, I decided to blow away the test code I had on my appengine and start over. Unfortunately setting up the quickstart was not as easy this time. After following the usual steps of setting up a project, creating the client IDs and configuring the project with the proper information, I deployed it and became stuck in an authorization redirect loop. The only error I received in the Log viewer was: 

Get Token: datastore: no such entity

After double and triple and quadruple checking that I had all the right IDs everywhere, I figured out a way to be able to debug the project and start tracking down the issue. There are only a handful of URLs that the quickstart is configured to handle. Anything else and it will just return a 404 error, as it should. I decided to use this to my advantage by modifying the main.go file to change all of the sections that performed HTTP redirects to redirect to pages such as "/useridempty".
For example:
if userId == "" {
        //http.Redirect(w, r, "/auth", http.StatusFound)
http.Redirect(w, r, "/useridempty", http.StatusFound)
        return nil
}

This allowed me to track it down to line 84: t := authTransport(c, userId)
authTransport was returning nil. Continuing this into the util.go file, the line that was causing trouble was line 94, specifically the datastore.Get(c, key, tok) portion. Turns out, that the token needed to authenticate wasn't being stored in the database, to the error (and subsequently the redirect) being caused by this was accurate.

I went back to the oauth2callback method, since I knew that was getting called at least, and visually stepped through the code cross referencing what was happening with what the code should be doing. This lead me to the storeCredential method. The storeCredential method (used on line 78 in the auth.go and declared on line 83 in util.go. The storeCredential method returns an error, but that error was not being checked. I modified the usage of storeCredential in the auth.go file to return the error like so:
if err = storeCredential(c, userId, tok); err != nil {
        return fmt.Errorf("Unable to store credential: %s", err)
}
This resulted in the following error: Unable to store credential: datastore: unsupported struct field type: map[string]string
After some digging around, I found that storing map objects in the datastore is no longer supported. I'm not sure exactly when it became unsupported, but the fact of the matter remains that it just plain won't work any more. The Token object from the oauth2 library contained an "Extras" field of type map[string]string and since it was a Token object that was being stored in the datastore, that's why it's failing. The token never got saved, so of course it wasn't there when it tried to read it out, but with the way the demo was calling the storeCredential method, the error was being dropped and passing by silently. 

In order to fix the error, I created a simple "SimpleToken" struct that contained the same signature as the Token object, just without the "Extras" field. I also set up a couple of short methods to turn a oauth.Token into a SimpleToken and vice versa. In the util.go file, I changed the storeCredential method to take in a *SimpleToken instead of a *oauth.Token and the authTransport method to convert the oauth.Token object into a SimpleToken object before passing it to the datastore.Get method. In the auth.go file, the only thing that had to change was in the oauth2callbackHandler method. The method was updated to convert the oauth.Token object into a SimpleToken object before the call to storeCredential

Once these changes were completed and the project redeployed to appengine, everything loaded up properly and began working. It was a very annoying issue and troublesome to track down, but once the root problem was found, the fix was surprisingly simple. Once I get around to cleaning up the code a bit I'll fork the project and make a pull request so that anyone else pulling down the Go quickstart won't have these same issues. I'd hope that the oauth or datastore library would be updated to properly work around the change to the datastore that now prevents storing map types.


Comments

Popular posts from this blog

Happy Holidays, Catching up before the New Year, and Family Visits

So, I'm a few posts behind. I hope you'll all forgive me for taking some time off to spend with family and friends throughout the holiday season. After my last post on the way down to South Carolina to visit my parents, brother, and as many friends as I could, I have been quite busy. First, I brought my mom back up to Maryland with us to visit for a couple weeks following Thanksgiving. We had a good time and she very much enjoyed her stay. The trip to Union Station so she could catch her train taking her back was a little sad, but surprisingly Union Station is a seriously awesome Metro/Amtrak/Marc station. It felt very much like a mall or a large airport. There were three levels with food, shopping, souvenir shops, and more. It was quite something else. Not to mention it was decked out in lights for the holidays so it looked even more amazing. So, to catch everyone up on what's been going on, what is going on, and what will be going on: Since the last post, I am now g

Getting Fit, Glass and Relax, and Hacking Habits

A few weeks back  +Noble Ackerson  recommended a book that sounded interesting, but I didn't really want to spend the money on it at the time. That book was "The Power of Habit, by Charles Duhigg". Well, I received some Play Store gift card over the last few weeks due to being awesome at work and decided to pick it up. I haven't quite finished it yet, but I can without a doubt say that it will make you look at things in an entirely different way. You'll begin to recognize all the habits that you have and even the habits that your company has. The things that we do every day without knowing and without even questioning. It's astounding. One of the key aspects of the book though is that if you know and understand a habit, you can change it. I've started to utilize what the book details about habits to accomplish a few things that I've realized I want to do. First, I plan on utilizing the habit forming routines to get to the point that I exercise every

Hackathons, Android Courses, and Catching up

Wow, what the hell? I look away for one second and I've already missed two posts? That's not a great start to the year... The Android class I'm teaching is  off to a great start though. So far we're 3 lessons in and have covered quite a bit. So far we've added new activities, created some helper classes, connected to a web service and pulled down data, as well as authenticated, created some settings we can save and load, set up a SQLite database, stored records to it, pulled them out, and then turned them into objects for us to see on the screen. We've adjusted the colors and properties of the items at run time and even created and utilized BroadcastReceivers, Services, and more. I'm impressed with what the class has absorbed so far, and what I've learned by preparing the class. I'm really enjoying it and the more Android development I do, the more I learn it's capable of, and the more I like doing it. In fact, our project for the hackathon I a