ActionView::Template::Error(nil:NilClass 的未定义方法 `tr'
ActionView::Template::Error (undefined method `tr' for nil:NilClass
我正在测试 service-worker rails gem 并使用 VAPID 私有密钥和 public 密钥发送推送通知。我已经成功地在本地创建推送通知,但是当我部署到 heroku 时,应用程序在尝试转到推送通知页面时会引发上述错误。这是错误:
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'
这是我的 webpushclient,其中定义了 VAPID 键:
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
这是我用来调用 public 键的脚本:
<script type="text/javascript">
var publicKey = new Uint8Array(<%= WebpushClient.public_key_bytes %>);
</script>
<%= javascript_include_tag 'push-react' %>
正如我之前所说,它在本地有效。我想我可能忘了定义一个变量,我看过类似的帖子并且已经调试了很长一段时间,但没有运气。有什么建议么?我还想补充一点,我很新,所以如果这是一个明显的错误,我会完全理解。
您的错误来自此方法:
def self.public_key_bytes
Base64.urlsafe_decode64(public_key).bytes
end
查找 source code for Base64#urlsafe_decode64
,其定义为:
def urlsafe_decode64(str)
strict_decode64(str.tr("-_", "+/"))
end
这就是您的 undefined method 'tr' for nil:NilClass
的来源:public_key
。您定义的是:
def self.public_key
ENV['VAPID_PUBLIC_KEY']
end
...换句话说,你没有在生产服务器上设置环境变量。这就是为什么它在本地有效,但在生产中无效。
我正在测试 service-worker rails gem 并使用 VAPID 私有密钥和 public 密钥发送推送通知。我已经成功地在本地创建推送通知,但是当我部署到 heroku 时,应用程序在尝试转到推送通知页面时会引发上述错误。这是错误:
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'
这是我的 webpushclient,其中定义了 VAPID 键:
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
这是我用来调用 public 键的脚本:
<script type="text/javascript">
var publicKey = new Uint8Array(<%= WebpushClient.public_key_bytes %>);
</script>
<%= javascript_include_tag 'push-react' %>
正如我之前所说,它在本地有效。我想我可能忘了定义一个变量,我看过类似的帖子并且已经调试了很长一段时间,但没有运气。有什么建议么?我还想补充一点,我很新,所以如果这是一个明显的错误,我会完全理解。
您的错误来自此方法:
def self.public_key_bytes
Base64.urlsafe_decode64(public_key).bytes
end
查找 source code for Base64#urlsafe_decode64
,其定义为:
def urlsafe_decode64(str)
strict_decode64(str.tr("-_", "+/"))
end
这就是您的 undefined method 'tr' for nil:NilClass
的来源:public_key
。您定义的是:
def self.public_key
ENV['VAPID_PUBLIC_KEY']
end
...换句话说,你没有在生产服务器上设置环境变量。这就是为什么它在本地有效,但在生产中无效。