tinode / chat

Instant messaging platform. Backend in Go. Clients: Swift iOS, Java Android, JS webapp, scriptable command line; chatbots
GNU General Public License v3.0
12.11k stars 1.89k forks source link

Device platform always set to "web", even with React Native #180

Closed tiagoalves closed 6 years ago

tiagoalves commented 6 years ago

Subject of the issue

I'm integrating Tinode into our React Native application using the Tinode JS SDK and now I'm setting up Firebase Cloud Messaging which uses the native Firebase SDKs for each platform (Android and iOS).

I noticed that my client devices are stored in Tinode's MySQL database with platform=web. But there is Android-specific code in the push functionality of Tinode: https://github.com/tinode/chat/blob/master/server/push/fcm/push_fcm.go#L168

I still receive Firebase data messages correctly on my Android device. However, from the code it seems that for Android devices, I should be receiving a Firebase Notification.

The problem appears to be here: https://github.com/tinode/chat/blob/46052f925db1f8bfb0bc808f70b89da7381bef6b/server/utils.go#L576

Can we somehow explicitly set the client platform using setDeviceToken() or similar?

Just FYI, if it helps: in my own app I'm adding something like this to the user agent: [BTAID/com.example.appid; BTAV/0.1.43; BTDB/google; BTDM/Nexus 5X; BTOS/Android; BTOSV/7.1.1; BTC/example-api-client-js; BTCV/1.1.21]. This allows me to easily distinguish between the client SDK's language (JS), and the client platform (Android). It's also very easy to parse. It's what the Facebook app uses.

Is this a bug report of a feature request?

Your environment

Server-side

Client-side

Steps to reproduce

Call tinode.setDeviceToken('some token', true) in a React Native project with the Tinode JS SDK.

Expected behaviour

The clients' platform should be correctly interpreted as Android in the Tinode chat server.

Actual behaviour

All clients are considered web platform.

Server-side log

Copy server-side log here. You may also attach it to the issue as a file.

Client-side log

This is the "hi" message that is sent from my Android client using React Native:

{"hi":{"id":"70672","ver":"0.15.9-rc1","ua":"MyAppName (Chrome/70.0; MacIntel); tinodejs/0.15.9-rc1","dev":"my-fcm-device-token","lang":"en-US"}}

or-else commented 6 years ago

Is there a way for a library to detect when it's running as ReactNative?

or-else commented 6 years ago

What's the actual User-Agent of the app?

or-else commented 6 years ago

Is there a way to detect the underlying platform? How do you detect the platform, i.e, Android vs iOS?

or-else commented 6 years ago

Is it true that window.navigator.product === "ReactNative"? Any other field I can check to get the platform?

tiagoalves commented 6 years ago

Yes, window.navigator.product === "ReactNative".

An example user-agent for the fetch() request for the Android emulator: Mozilla/5.0 (Linux; Android 7.1.1; Android SDK built for x86 Build/NYC; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/55.0.2883.91 Mobile Safari/537.36

Detecting the platform:

import { Platform } from "react-native";

console.log(Platform.OS); // either "ios" or "android"

But these strategies would only work for React Native. Maybe allowing the developer to provide (override) the platform could help.

or-else commented 6 years ago

Thanks. It will be fixed in the next release. I'll add an option for setting platform explicitly together with the token and also auto-detect ReactNative as a backup.

or-else commented 6 years ago

Released in v0.15.9-rc2 https://github.com/tinode/chat/commit/b663b9e2028b3ed0724f10aa304a9e3d1547bf5b