diff --git a/browserid/static/dialog/resources/channel.js b/browserid/static/dialog/resources/channel.js
index 904bc27e6a7e176de2838eaf2fe7919940d73fa8..b432b3621e936736d8c8a319826d019120832986 100644
--- a/browserid/static/dialog/resources/channel.js
+++ b/browserid/static/dialog/resources/channel.js
@@ -52,12 +52,31 @@
 
 
 (function() {
+  function getUrlVars() {
+    var hashes = window.location.href.slice(
+                    window.location.href.indexOf('#') + 1).split('&');
+        vars = {};
+
+    for(var i = 0, item, hash; item=hashes[i]; ++i) {
+      hash = hashes[i].split('=');
+      vars[hash[0]] = hash[1];
+    }
+
+    return vars;
+  }
+
+  function getRelayName() {
+    var vars = getUrlVars();
+    return vars.relay;
+  }
+
   function getRelayWindow(callback) {
-    var frames = window.opener.frames;
-    var frameWindow;
+    var frames = window.opener.frames,
+        frameWindow,
+        relayName = getRelayName();
 
     try {
-      frameWindow = frames['browserid_relay'];
+      frameWindow = frames[relayName];
       // Make sure that we have our frameWindow as well as the two functions we 
       // care about before saying that we are ready.
       if (frameWindow && frameWindow.register_dialog && frameWindow.browserid_relay) {
@@ -67,10 +86,8 @@
     } catch(e) {
       // if the relay iframe does not yet exist, or if its contents are not yet 
       // loaded, we get a security exception.
-      console.log(e);
     }
 
-    console.log('relay or functions not found, retrying');
     // not ready yet, check in 100ms
     setTimeout(getRelayWindow.bind(null, callback), 500);
   }
diff --git a/browserid/static/include.js b/browserid/static/include.js
index 85603898e4dfb1c5864f032ed28532dbf5e8743a..6c88f8b3ea82661f89e7615653b1adbb773d6b9c 100644
--- a/browserid/static/include.js
+++ b/browserid/static/include.js
@@ -562,7 +562,7 @@ if (!navigator.id.getVerifiedEmail || navigator.id._getVerifiedEmailIsShimmed)
   })();
 
 
-  var chan, w, iframe;
+  var chan, w, iframe, relayframe_opencount=0;
 
   // this is for calls that are non-interactive
   function _open_hidden_iframe(doc) {
@@ -573,20 +573,31 @@ if (!navigator.id.getVerifiedEmail || navigator.id._getVerifiedEmailIsShimmed)
     return iframe;
   }
   
-  function _open_relay_frame(doc) {
+  function _get_relayframe_name() {
+    var framename = 'browserid_relay' + relayframe_opencount;
+    relayframe_opencount++;
+    return framename;
+  }
+
+  function _open_relayframe(framename) {
+    var doc = window.document;
     var iframe = doc.createElement("iframe");
-    iframe.setAttribute('name', 'browserid_relay');
+    iframe.setAttribute('name', framename);
     iframe.setAttribute('src', ipServer + "/relay");
     iframe.style.display = "none";
     doc.body.appendChild(iframe);
+
     return iframe;
   }
   
-  function _open_window() {
+  function _open_window(framename) {
     // FIXME: need to pass the location in a more trustworthy fashion
-    // HOW? set up a direct reference to the open window
+    // We have to change the name of the relay frame every time or else Firefox 
+    // has a problem re-attaching new iframes with the same name.  Code inside 
+    // of frames with the same name sometimes does not get run.
+    // See https://bugzilla.mozilla.org/show_bug.cgi?id=350023
     return window.open(
-      ipServer + "/sign_in", "_mozid_signin",
+      ipServer + "/sign_in#relay=" + framename, "_mozid_signin",
       isMobile ? undefined : "menubar=0,location=0,resizable=0,scrollbars=0,status=0,dialog=1,width=520,height=350");
   }
 
@@ -596,6 +607,25 @@ if (!navigator.id.getVerifiedEmail || navigator.id._getVerifiedEmailIsShimmed)
     }      
   }
 
+  function _attach_event(element, name, listener) {
+    if (element.addEventListener) {
+      element.addEventListener(name, listener, false);
+    }
+    else if(element.attachEvent) {
+      // IE < 9
+      element.attachEvent(name, listener);
+    }
+  }
+
+  function _detatch_event(element, name, listener) {
+    if (element.removeEventListener) {
+      element.removeEventListener(name, listener, false);
+    }
+    else if(element.detachEvent) {
+      element.detachEvent(name, listener);
+    }
+  }
+
   // keep track of these so that we can re-use/re-focus an already open window.
   navigator.id.getVerifiedEmail = function(callback) {
     if (w) {
@@ -604,18 +634,12 @@ if (!navigator.id.getVerifiedEmail || navigator.id._getVerifiedEmailIsShimmed)
       return;
     }
 
-    var doc = window.document;
-    iframe = _open_relay_frame(doc);
-    w = _open_window();
+    var framename = _get_relayframe_name();
+    var iframe = _open_relayframe(framename);
+    w = _open_window(framename);
 
     // if the RP window closes, close the dialog as well.
-    if (window.addEventListener) {
-      window.addEventListener('unload', _close_window, false);
-    }
-    else if(window.attachEvent) {
-      // IE < 9
-      window.attachEvent('unload', _close_window);
-    }
+    _attach_event(window, 'unload', _close_window);
 
     // clean up a previous channel that never was reaped
     if (chan) chan.destroy();
@@ -631,13 +655,7 @@ if (!navigator.id.getVerifiedEmail || navigator.id._getVerifiedEmailIsShimmed)
       iframe.parentNode.removeChild(iframe);
       iframe = null;
 
-
-      if (window.removeEventListener) {
-        window.removeEventListener('unload', _close_window, false);
-      }
-      else if(window.detachEvent) {
-        window.detachEvent('unload', _close_window);
-      }
+      _detatch_event(window, 'unload', _close_window);
     }
 
     chan.call({
@@ -758,7 +776,6 @@ if (!navigator.id.getVerifiedEmail || navigator.id._getVerifiedEmailIsShimmed)
       method: method,
       params: args,
       success: function(rv) {
-        console.log(method + " channel returned: rv is " + rv);
         if (onsuccess) {
           onsuccess(rv);
         }