【问题标题】:Rails turbolinks server with react-native-webview app and firebase messaging带有 react-native-webview 应用程序和 firebase 消息传递的 Rails turbolinks 服务器
【发布时间】:2021-07-29 07:08:42
【问题描述】:

我有以下设置:

一个 Rails 服务器,它有一个使用 devise gem 的基本用户登录。 在那里我定义了一个User 和一个Device 模型,其中每个用户可以通过用户上的has_many 关系拥有多个设备。 Device 模型有一个属性——一个令牌,我将使用它来发送推送通知以使用 rpush gem。

使用 react-native-webview 包和 react-native-firebase/messaging 包的 react-native 应用程序。问题是,我真的不知道如何正确地将 firebase 设备令牌发送到服务器。

到目前为止,我已经将 rails devise registrations#new 视图覆盖为以下内容:

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= render "devise/shared/error_messages", resource: resource %>

  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
  </div>

  <div class="field">
    <%= f.label :password %>
    <% if @minimum_password_length %>
    <em>(<%= @minimum_password_length %> characters minimum)</em>
    <% end %><br />
    <%= f.password_field :password, autocomplete: "new-password" %>
  </div>

  <div class="field">
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
  </div>

  <%= f.fields_for :devices, @user do |f| %>
    <div class="field">
      <%= f.hidden_field :token, {value: nil} %>
    </div>
  <% end %>

  <div class="actions">
    <%= f.submit "Sign up" %>
  </div>
<% end %>

<%= render "devise/shared/links" %>

在这里您可以看到我为令牌添加了一个隐藏字段,当我使用以下代码登陆 /users/sign_up 页面后,我将其插入到 react-native 应用程序中:

import React, { useState } from "react";
import { WebView } from "react-native-webview";
import messaging from '@react-native-firebase/messaging';

const MyWebView = () => {
  const [uri] = useState("http:\/\/10.0.2.2:3000");
  const [webViewRef, setWebViewRef] = useState(null);

  const postMessageThatTurbolinksLoadOccured = `
    document.addEventListener("turbolinks:load", () => {
      window.ReactNativeWebView.postMessage("turbolinks:load");
    })`;

  function onMessage(obj) {
    const event = obj.nativeEvent;

    if(event.data != "turbolinks:load") return;

    if(event.url==`${uri}/users/sign_in` || event.url==`${uri}/users/sign_up`) {
      messaging().getToken().then(token => {
        const insertTokenCode = `
          document.getElementById("user_devices_attributes_0_token").value = "${token}";
        `;
        webViewRef.injectJavaScript(insertTokenCode);
      })
    }
  }

  // This is here only temporarily
  messaging().onMessage(remoteMessage => {
    Alert.alert(remoteMessage.notification.body);
  })

  return (
    <WebView
      ref={setWebViewRef}
      source={{ uri: `${uri}/users/sign_in` }}
      injectedJavaScript={postMessageThatTurbolinksLoadOccured}
      onMessage={onMessage}
    />
    );
};

export default MyWebView;

这实际上工作正常,但是一旦我开始测试 rails 应用程序并尝试在规范中设置隐藏字段值,我得到了一个错误:

     Selenium::WebDriver::Error::ElementNotInteractableError:
       element not interactable

这让我觉得这种方法很“hacky”。那么有人知道更好的方法吗?

【问题讨论】:

    标签: ruby-on-rails firebase react-native devise firebase-cloud-messaging


    【解决方案1】:

    对于同样遇到此问题的任何人,我前一阵子想通了,但还没有回答这个问题。

    我开始使用 firebase 通道,而不必在服务器上注册每个设备,然后将消息发送到通道,这样我就无需在服务器上保存每个设备 ID。像这样:

    • 对于 react-native 应用程序
    import { Alert } from "react-native";
    import { WebView } from "react-native-webview";
    import messaging from '@react-native-firebase/messaging';
    
    const MyView = () => {
      const messagingInstance = messaging()
      messagingInstance.subscribeToTopic("welcome").then(() => {
        messagingInstance.onMessage(message => {
          if(message.from == "/topics/welcome") {
            Alert.alert(message.notification.body);
            messagingInstance.unsubscribeFromTopic("welcome");
          }
        });
      });
    
      return (
        <WebView
          source={{ uri: `http:\/\/10.0.2.2:3000` }}
        />
        );
    };
    export default MyView;
    
    • 在服务器上我有一个工作,它使用fcm gem 通过通道发送通知
    class SendGreetingPushNotificationJob < ApplicationJob
      queue_as :default
    
      def perform(*args)
        fcm = FCM.new(Rails.application.config.FIREBASE_SERVER_KEY)
        fcm.send_to_topic("welcome", notification: {body: "Welcome to MyApp!"})
      end
    end
    

    【讨论】:

      猜你喜欢
      • 2018-05-27
      • 2020-10-27
      • 2023-04-01
      • 1970-01-01
      • 2012-03-04
      • 1970-01-01
      • 1970-01-01
      • 2017-06-10
      相关资源
      最近更新 更多