javascriptreact-nativenotificationssymfony4mercure

react native can't subscribe to mercure backend notifications


I'm working on a notifications system with React Native and Symfony. I configured Mercure with docker to handle front subscription to real time updates : the .env file :

###> symfony/mercure-bundle ###
# See https://symfony.com/doc/current/mercure.html#configuration
MERCURE_PUBLISH_URL=http://mercure.localhost/.well-known/mercure
# The default token is signed with the secret key: !ChangeMe!
MERCURE_JWT_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdfX0.9-LscFk3QfdDtZ4nyg6BiH4_qDm6pbYHydURBMsDgEc
###< symfony/mercure-bundle ###

mercure.yaml:

mercure:
    enable_profiler: '%kernel.debug%'
    hubs:
        default:
            url: '%env(MERCURE_PUBLISH_URL)%'
            jwt: '%env(MERCURE_JWT_TOKEN)%'

I created a Notifications component in my React Native application and i use the code in the official documentation of symfony mercure: https://symfony.com/doc/4.3/mercure.html#subscribing Notifications.js code :

import React, { Component } from 'react';
import { View, Text } from 'react-native';

export default class Notifications extends Component {
    constructor(props) {
        super(props);
        this.state = {
        };
    }

    componentDidMount() {
        const url = new URL('http://mercure.localhost/.well-known/mercure');
        url.searchParams.append('topic', 'http://dev.api.partage-mandats.proprietes-privees.com/mandate_shares/{id}');

        url.searchParams.append('topic', 'http://example.com/books/1');
        const eventSource = new EventSource(url);

        eventSource.onmessage = e => console.log(e);
    }

    render() {
        return (
            <View>
                <Text> Notifications </Text>
            </View>
        );
    }
}

I tested with Postan and i get a valid response : Postman test mercure

And i tried the javaScript code in a html file for testing :

<script type="text/javascript">

const url = new URL('http://mercure.localhost/.well-known/mercure');
url.searchParams.append('topic', 'http://dev.api.partage-mandats.proprietes-privees.com/mandate_shares/{id}');

url.searchParams.append('topic', 'http://example.com/books/1');
const eventSource = new EventSource(url);

eventSource.onmessage = e => console.log(e); 
</script>
</html>

And i get a real time response when i run request with Postman : console log in html file My problem is that URL, searchParams and eventSource are not compatible with react native. How can i transform this javaScript code to react native valid code ? I tried to install some librairies : whatwg-url, buffer, react-native-event-source and my current code is :

import React, { Component } from 'react';
import { View, Text } from 'react-native';

import { URL, URLSearchParams } from 'whatwg-url';
import { Buffer } from 'buffer';
import RNEventSource from 'react-native-event-source';

export default class Notifications extends Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }

  componentDidMount() {
    global.Buffer = Buffer;
    global.URL = URL;
    global.URLSearchParams = URLSearchParams;
    global.EventSource = RNEventSource;

    const url = new global.URL('http://mercure.localhost/.well-known/mercure');
    url.global.URLSearchParams.append('topic', 'http://dev.api.partage-mandats.proprietes-privees.com/mandate_shares/{id}');

    url.global.URLSearchParams.append('topic', 'http://example.com/books/1');
    const eventSource = new global.EventSource(url);

    eventSource.onmessage = e => console.log(e); 
  }

  render() {
    return (
      <View>
        <Text> Notifications </Text>
      </View>
    );
  }
}

I got this error : undefined is not an object (evaluating 'url.global.URLSearchParams')


Solution

  • I fix the issue, it was about the publish url I can't use a local url so i create a host and i config the url like this :

    http://mercure.preprod.oryx-immobilier.com/.well-known/mercure

    Now i can receive real time response from the backned