简体   繁体   中英

ActionView::Template::Error (undefined method `tr' for nil:NilClass

I am testing out the service-worker rails gem and am using VAPID private and public keys to send push notifications. I've succesfully been able to create push notifications locally, but when I deploy to heroku, the app raises the error stated above when trying to go to the push notification page. Here is the error:

      75] Started GET "/push-simple/" for 69.253.120.203 at 2017-02-12 06:37:35 +0000
2017-02-12T06:37:35.339318+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75] ActionView::Template::Error (undefined method `tr' for nil:NilClass
2017-02-12T06:37:35.333379+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75]   Rendering pages/push-simple.html.erb within layouts/application
2017-02-12T06:37:35.332337+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75] Processing by PagesController#show as HTML
2017-02-12T06:37:35.336377+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75]   Rendered pages/push-simple.html.erb within layouts/application (2.8ms)
2017-02-12T06:37:35.336998+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75] Completed 500 Internal Server Error in 4ms
2017-02-12T06:37:35.339281+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75]   
2017-02-12T06:37:35.339490+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75]     13: <script type="text/javascript">
2017-02-12T06:37:35.339320+00:00 app[web.1]: Did you mean?  try):
2017-02-12T06:37:35.339489+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75]     11: </div>
2017-02-12T06:37:35.339489+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75]     12: 
2017-02-12T06:37:35.339561+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75] app/views/pages/push-simple.html.erb:14:in `_app_views_pages_push_simple_html_erb__2838769268823495646_39526220'
2017-02-12T06:37:35.339491+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75]     15: </script>
2017-02-12T06:37:35.339491+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75]     14:   var publicKey = new Uint8Array(<%= WebpushClient.public_key_bytes %>);
2017-02-12T06:37:35.339492+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75]     16: <%= javascript_include_tag 'push-simple' %>
2017-02-12T06:37:35.339520+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75]   
2017-02-12T06:37:35.339560+00:00 app[web.1]: [3d626b62-4c1b-41ca-aad3-fc653dc96b75] app/clients/webpush_client.rb:7:in `public_key_bytes'

And here is my webpushclient where the VAPID keys are defined:

  class WebpushClient
    def self.public_key
      ENV['VAPID_PUBLIC_KEY']
    end

    def self.public_key_bytes
      Base64.urlsafe_decode64(public_key).bytes
    end

    def self.private_key
      ENV['VAPID_PRIVATE_KEY']
    end

    # Send webpush message using subscription parameters
    #
    # @param message [String] text to encrypt
    # @param subscription_params [Hash<Symbol, String>]
    # @option subscription_params [String] :endpoint url to send encrypted message
    # @option subscription_params [Hash<Symbol, String>] :keys auth keys to send with message for decryption
    # @return true/false
    def send_notification(message, endpoint: "", p256dh: "", auth: "")
      raise ArgumentError, ":endpoint param is required" if endpoint.blank?
      raise ArgumentError, "subscription :keys are missing" if p256dh.blank? || auth.blank?

      Rails.logger.info("Sending WebPush notification...............")
      Rails.logger.info("message: #{message}")
      Rails.logger.info("endpoint: #{endpoint}")
      Rails.logger.info("p256dh: #{p256dh}")
      Rails.logger.info("auth: #{auth}")

      Webpush.payload_send \
        message: message,
        endpoint: endpoint,
        p256dh: p256dh,
        auth: auth,
        vapid: {
          subject: "jon.corrin@gmail.com",
          public_key: public_key,
          private_key: private_key
        }
    end

    def public_key
      self.class.public_key
    end

    def private_key
      self.class.private_key
    end
  end

and here is the script im using to call the public key:

<script type="text/javascript">
  var publicKey = new Uint8Array(<%= WebpushClient.public_key_bytes %>);
</script>
<%= javascript_include_tag 'push-react' %>

Like I said before, it works locally. I think I may have forgotten to define a variable, I've looked at similar posts and have been debugging for quite some time, but have had no luck. Any suggestions? I also want to add, I'm quite new, so if it's an obvious error, I'll completely understand.

Your error is coming from this method:

def self.public_key_bytes
  Base64.urlsafe_decode64(public_key).bytes
end

Looking up the source code for Base64#urlsafe_decode64 , this is defined by:

def urlsafe_decode64(str)
  strict_decode64(str.tr("-_", "+/"))
end

This is where your undefined method 'tr' for nil:NilClass must be coming from: the public_key . Which you have defined by:

def self.public_key
  ENV['VAPID_PUBLIC_KEY']
end

...In other words, you have not set the environmental variable on your production server. That's why it works locally, but not on production.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM