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.


  1. Users slowly get a greater rate until they get to tier 6, the place the commission rate is 50%. MBit allows its customers to refer their friends, family, and other people|and folks} 카지노사이트 they know to earn additional money. The customers generate their very own affiliate code which might then be shared with others. Even although this offer can solely be loved by new customers, there are other offers available on mBit for all their account holders. The user’s new account could be created and their bonus could be deposited into the account. Complete the signup process and perform any further verification checks that are be} required.


Post a Comment

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

Let's get this started

If you can read this then I guess I've set up the DNS records and account settings correctly. This first post comes to you, as I'm sure many of them will, from my Android device. I hope to use this blog to help with keeping my myriad projects I have in line as well as to keep track of ideas for new projects I'd like to take on once I have some additional room on my plate. I'll keep this short so it doesn't burn through your attention span (and mine). ;p I like to build things, be them digital or physical. I like to consider myself on the path to becoming a great code ninja. Although I have been trained in the coding arts, as with any great skill, it takes time, effort, and much, much practice to hone those abilities. From time to time I'll take on a project that involves creating something tangible. Those projects are a little more varied than my digital ones. My current list contains items as strange as building a kayak and a couch. I'll wrap up thi