title: Generate the VAPID public key in Rails and pass it to Javascript
body: <p>In order to use the Push API with VAPID I need an <code>applicationServerKey</code>:</p>
  
  <pre><code>serviceWorkerRegistration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: applicationServerKey // we've got it with getApplicationServerKey() defined below
  });
  </code></pre>
  
  <p>I generate it on the server side with Ruby:</p>
  
  <pre><code>ecdsa_private_key = OpenSSL::PKey::EC.new 'prime256v1'
  ecdsa_private_key.generate_key
  sender.vapid_private_key = ecdsa_private_key.to_pem
  
  ecdsa_public_key = OpenSSL::PKey::EC.new ecdsa_private_key
  ecdsa_public_key.private_key = nil
  sender.vapid_public_key = ecdsa_public_key.to_pem
  </code></pre>
  
  <p>Then I have to download it:</p>
  
  <pre><code>getApplicationServerKey: function () {
    return new Promise(function (resolve, reject) {
      var request = new Request('https://example.com/application_server_key');
      fetch(request).then(function (response) {
        response.text().then(function (base64) {
          resolve(_.base64ToArrayBuffer(base64));
        });
      });
    });
  },
  base64ToArrayBuffer: function (base64) {
    var binary_string = window.atob(base64);
    var len = binary_string.length;
    var bytes = new Uint8Array(len);
    for (var i = 0; i &lt; len; i++) {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes.buffer;
  }
  </code></pre>
  
  <p>The key is returned as a base64 string from the controller:</p>
  
  <pre><code>ecdsa_public_key = OpenSSL::PKey.read @sender.vapid_public_key
  base64 = Base64.encode64(ecdsa_public_key.public_key.to_bn.to_s(2))
  render text: base64
  </code></pre>
  
  <p>The problem is that Firefox returns this error when I call <code>pushManager.subscribe</code>:</p>
  
  <pre><code>DOMException [InvalidAccessError: "Invalid raw ECDSA P-256 public key."
  code: 15
  nsresult: 0x8053000f]
  </code></pre>
  
  <p>Any help is appreciated.</p>
  
  <p><strong>UPDATE</strong>: it's driving me crazy... I've also tried encoding / decoding with hex instead of base64, but I get the same error. </p>
  
  <p>From Ruby:</p>
  
  <pre><code>$ ecdsa_public_key.to_text
  =&gt; "Private-Key: (256 bit)\npub: \n
  04:28:a9:89:be:8a:a8:f2:f1:bf:ed:04:d2:28:e9:\n
  70:e9:b7:f3:8c:3c:f7:20:dc:95:30:1a:72:77:66:\n
  09:0d:29:f6:6c:6c:c8:45:6e:da:ac:05:d6:ff:43:\n
  9a:66:d0:c3:4c:bc:4a:0f:a3:ad:e8:23:33:22:40:\n
  20:9e:de:14:56\n
  ASN1 OID: prime256v1\n
  NIST CURVE: P-256\n"
  
  $ ecdsa_public_key.public_key.to_bn.to_s 16
  =&gt; "0428A989BE8AA8F2F1BFED04D228E970E9B7F38C3CF720DC95301A727766090D29F66C6CC8456EDAAC05D6FF439A66D0C34CBC4A0FA3ADE823332240209EDE1456"
  </code></pre>
  
  <p>As you can see it is a P-256 key (I don't know why it says Private-Key instead of Public Key, but, as you can see from the code that generates it, it is a public key).</p>
  
  <p>Then I download the hex string with Javascript <code>fetch</code> and this is what I get: </p>
  
  <pre><code>0428A989BE8AA8F2F1BFED04D228E970E9B7F38C3CF720DC95301A727766090D29F66C6CC8456EDAAC05D6FF439A66D0C34CBC4A0FA3ADE823332240209EDE1456
  
  Array [ "04", "28", "A9", "89", "BE", "8A", "A8", "F2", "F1", "BF", 55 more… ]
  
  Uint8Array [ 4, 40, 169, 137, 190, 138, 168, 242, 241, 191, 55 more… ]
  
  ArrayBuffer { byteLength: 65 } // I get it by calling .buffer on the Uint8Array
  
  DOMException [InvalidAccessError: "Invalid raw ECDSA P-256 public key."
  code: 15
  nsresult: 0x8053000f]
  </code></pre>
  
  <p>As you can see from the intermediate steps that I print in the console, the key is processed correctly. However I still get that error...</p>
  
  <p><strong>UPDATE 2</strong>: The same code works successfully in Chrome: I managed to send a notification using VAPID. It's probably a Firefox bug.</p>