I am trying to send a push notification to my ios device from the Firebase console by token ID. I am using react-native-firebase to allow the app to perform actions based on the notification events. I followed the instructions to integrate the SDK and have set up the APNS certs etc:
http://invertase.io/react-native-firebase/#/installation-ios
My firebase.js config file looks like this:
import RNFirebase from 'react-native-firebase';
const configurationOptions = {
debug: true
};
const firebase = RNFirebase.initializeApp(configurationOptions);
export default firebase;
My main React component looks like this:
import React, { Component } from 'react'
import {
Text,
View,
Alert,
Platform
} from 'react-native'
import firebase from './firebase'
export default class extends Component {
constructor(props) {
super(props)
this.state = {
token: ''
}
}
componentDidMount() {
firebase.messaging().getToken()
.then((token) => {
this.setState({ token })
console.log('token: ', token)
})
firebase.messaging().getInitialNotification()
.then((notification) => {
console.log('Notification which opened the app: ', notification)
})
firebase.messaging().onMessage((message) => {
console.log('messaging', message)
})
firebase.messaging().onTokenRefresh((token) => {
console.log('Refreshed FCM token: ', token)
})
}
render() {
return (
<View style={{ marginTop: 22 }}>
<Text>{this.state.token}</Text>
</View>
)
}
}
I successfully get the token when the component mounts and then use that in the Firebase console to send a notification, but the notification is not received. I am using a real device, not and iPhone. I am using a development provisioning profile with Push notifications enabled and the remove notifications back ground entitlement enabled successfully, along with the appropriate development APNs certificate, which has been uploaded to the firebase console.
Why am I not receiving the notification on the device?
Okay, it looks like it was just ignoring the remote notifications because I had not requested permissions from the user. Just needed to do that via the SDK:
componentDidMount() {
firebase.messaging().requestPermissions()
firebase.messageing().getToken().then...
Related
I have a react APP that uses the AWS Amplify PubSub library.
I have an IoT device that connect to AWS IoT and publishes message on topic/pub (topic).The message is only sent once (from the device) and when I see it in the AWS MQTT client console I can only see only 1 message (as expected) but in the react application I'm receiving multiple messages in the console.
App.js
...
import {Amplify} from 'aws-amplify';
import awsconfig from './aws-exports';
// import { withAuthenticator } from 'aws-amplify-react'; // or 'aws-amplify-react-native';
import { withAuthenticator, Button, Heading } from '#aws-amplify/ui-react';
import '#aws-amplify/ui-react/styles.css';
import { Auth } from 'aws-amplify';
Amplify.configure(awsconfig);
// Auth.currentCredentials().then(creds => console.log(creds));
function App() {
return (
...
export default withAuthenticator(App,true);
Device Page.js
import {Amplify} from 'aws-amplify';
import awsconfig from './../aws-exports';
import { PubSub } from 'aws-amplify';
import { AWSIoTProvider } from '#aws-amplify/pubsub/lib/Providers';
Amplify.configure(awsconfig);
Amplify.addPluggable(new AWSIoTProvider({
aws_pubsub_region: 'xx-xxxxxxx-x',
aws_pubsub_endpoint: 'wss://<My endpoint from AWS IoT>/mqtt',
}));
function GaugesComponent ({id}) {
PubSub.subscribe('test/pub').subscribe({
next: data => {
console.log(data.value);
},
error: error => console.error(error),
complete: () => console.log('Done'),
},);
return (
...
export default GaugesComponent;
When my device publishes or I use the AWS MQTT client to publish a message the message is logged multiple times in the console.
Images:
AWS MQTT client console
console log messages of react app
Instead of adding the below code in the device.js where I'm subscribing to the MQTT topic I only added it once in my app.js after Amplify.configure(); like this
App.js
Amplify.configure(awsconfig);
Amplify.addPluggable(new AWSIoTProvider({
aws_pubsub_region: 'xx-xxxxxxx-x',
aws_pubsub_endpoint: 'wss://<My endpoint from AWS IoT>/mqtt',
}));
Then I subscribe to the topic using useEffect() like this in my device.js
Device.js
sub_topic = PubSub.subscribe(id+'/live').subscribe({
next: data => {/*do stuff with received data*/},
error: error => console.error(error),
complete: () => console.log('Done'),
},);
return ()=>{
sub_topic.unsubscribe();
console.log("Unsubscribed to topic");
}
},[]);
I have an app that persists some values in a cookie. I know that there are other tools such as useState, useContext, etc... but this particular app works with a library that stores information in a jwt so I have to read certain values by fetching the jwt. I am porting the app from next.js 12 (with webpack) to next.js 13 (with turbopack).
I've already ported the app structurally to fit the app style routing of next.js 13. My pages all go in their individual folders with sub layouts WITHIN the app directory, and I have a master layout and homepage directly in the app directory.
The old code for my protected page in next.js 12 looked like this:
protected.tsx
import type { NextPage } from 'next';
import { GetServerSideProps } from 'next';
import { useContext } from 'react';
//#ts-ignore
import Cookies from 'cookies';
const Protected: NextPage = (props: any) => {
if (!props.authorized) {
return (
<h2>Unauthorized</h2>
)
} else {
return (
<div className="max-w-md">
<h1 className="font-bold">This is the Protected Section</h1>
</div>
)}
}
export const getServerSideProps: GetServerSideProps = async ({ req, res, query }) => {
const { id } = query
const cookies = new Cookies(req, res)
const jwt = cookies.get('<MY TOKEN NAME>')
if (!jwt) {
return {
props: {
authorized: false
},
}
}
const { verified } = <MY TOKEN SDK INSTANCE>.verifyJwt({ jwt })
return {
props: {
authorized: verified ? true : false
},
}
}
export default Protected
I have this page moved into it's own directory now.
"getServerSideProps" isn't supported in Next.js 13 https://beta.nextjs.org/docs/data-fetching/fundamentals. The docs say "previous Next.js APIs such as getServerSideProps, getStaticProps, and getInitialProps are not supported in the new app directory." So how would I change my code to work in Next.js 13?
P.S. I know what it looks like but this cookie IS NOT HANDLING USER AUTHENTICATION. I understand that someone could alter the cookie and gain access to the protected page. This is just a small piece of a larger app with other security mechanisms that I have in place.
import { cookies } from "next/headers";
this is next/headers.js cookie function
function cookies() {
(0, _staticGenerationBailout).staticGenerationBailout('cookies');
const requestStore = _requestAsyncStorage.requestAsyncStorage && 'getStore' in _requestAsyncStorage.requestAsyncStorage ? _requestAsyncStorage.requestAsyncStorage.getStore() : _requestAsyncStorage.requestAsyncStorage;
return requestStore.cookies;
}
this is making a request to the client side to get the cookie. In app directory, you are on the server and you can write this inside the component.
const cookie = cookies().get("cookieName")?.value
you can access to your cookie via "cookies-next" library.
pnpm i cookies-next
check this out : https://www.npmjs.com/package/cookies-next
I created a Google Cloud Platform account, and made a simple hello_world type Python "Cloud Function" that just spits out some simple text. I made this function "HTTP" accessible and only able to be called/authenticated by a "Service Account" that I made for the purpose of calling this very function. I generated a key for this "Service Account" and downloaded the json file for the key.
The problem is that I can't find any documentation on how to call this function with my service account in a next.js app. I tried this:
import React from 'react';
import { Button } from 'react-bootstrap';
import { GoogleAuth } from 'google-auth-library';
const projectId = 'gtwitone';
const keyFilename = '/Users/<myusername>/path/to/cloudfunction/credentials.json';
class Middle extends React.Component {
handleClick() {
console.log('this is:', this);
}
// This syntax ensures `this` is bound within handleClick. // Warning: this is *experimental* syntax. handleClick = () => { console.log('this is:', this); }
/* async listFunctions() {
const [functions] = await client.listFunctions();
console.info(functions);
} */
async runGoogleCloudFunctionTest() {
// Define your URL, here with Cloud Run but the security is exactly the same with Cloud Functions (same underlying infrastructure)
const url = "https://us-central1-<projectname>.cloudfunctions.net/<functionname>"
//Example with the key file, not recommended on GCP environment.
const auth = new GoogleAuth({keyFilename: keyFilename})
//Create your client with an Identity token.
const client = await auth.getIdTokenClient(url);
const res = await client.request({url});
console.log(res.data);
}
render() {
return (
<div className="col-md-12 text-center">
<Button variant='primary' onClick={this.runGoogleCloudFunctionTest}>
Click me
</Button>
</div>
);
}
}
export default Middle;
But I got this error in my terminal:
<myusername>#<mycomputername> <thisnextjsappdirectory> % yarn dev
yarn run v1.22.17
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
wait - compiling...
event - compiled client and server successfully in 267 ms (124 modules)
wait - compiling / (client and server)...
wait - compiling...
error - ./node_modules/google-auth-library/build/src/auth/googleauth.js:17:0
Module not found: Can't resolve 'child_process'
Import trace for requested module:
./node_modules/google-auth-library/build/src/index.js
./components/Middle.tsx
./pages/index.tsx
https://nextjs.org/docs/messages/module-not-found
Native Node.js APIs are not supported in the Edge Runtime. Found `child_process` imported.
Could not find files for / in .next/build-manifest.json
Could not find files for / in .next/build-manifest.json
^C
<myusername>#<mycomputername> <thisnextjsappdirectory> %
I know that this is problem with server side rendering in my Next.js app and people recommend using a client side package like this https://github.com/google/google-api-javascript-client. But google-api-javascript-client doesn't have any documentation on authenticating with a .json credentials file instead of an API KEY which I do not have.
In short how do I get my app to work and run the Google Cloud function with a .json credentials file for am authenticated service account?
I fixed it by simply moving the GoogleAuth api call to the pages/api route.
pages/api/google.ts
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next"
import { GoogleAuth } from "google-auth-library"
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
const url = process.env.FUNCTION_URL as string
//Example with the key file, not recommended on GCP environment.
const auth = new GoogleAuth({ keyFilename: process.env.KEYSTORE_PATH })
//Create your client with an Identity token.
const client = await auth.getIdTokenClient(url)
const result = await client.request({ url })
console.log(result.data)
res.json({ data: result.data })
}
components/Middle.tsx
import React from "react"
import { Button } from "react-bootstrap"
class Middle extends React.Component {
handleClick() {
console.log("this is:", this)
}
// this talks with /pages/api/google
async imCallingAnAPI() {
const result = await fetch("/api/google")
console.log({ result })
}
render() {
return (
<div className="col-md-12 text-center">
<Button variant="primary" onClick={this.imCallingAnAPI}>
Click me
</Button>
</div>
)
}
}
export default Middle
pages/index.tsx
import type { NextPage } from 'next'
import Header from '../components/Header';
import Footer from '../components/Footer';
import Middle from '../components/Middle';
const Home: NextPage = () => {
return (
<><main className='d-flex flex-column min-vh-100'>
<Header />
<br></br>
<br></br>
<Middle />
</main>
<footer>
<Footer />
</footer>
</>
)
}
export default Home
I think that next.js has trouble loading GoogleAuth in a component. I'm not 100% sure why, but I think it has to do with next.js not knowing exactly how to handle GoogleAuth with server-side rendering.
Im getting a problem when i want to send data from React Component to hub It's Not send...
Note Hub is connected to client But Data Not Send/Recieve
Hub Code
public void SendMessageToAll(string userName, string message)
{
Clients.All.messageReceived(userName, message );
}
React Js Code:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { hubConnection } from 'signalr-no-jquery';
class Dashboard extends Component {
constructor(props) {
super(props);
const connection = hubConnection('https://localhost:44332');
const hubProxy = connection.createHubProxy('Chat');
hubProxy.on('Hello', function(name) {
console.log(name);
});
// atempt connection, and handle errors
connection.start()
.done(function(){ console.log('Now connected, connection ID=' + connection.id); })
.fail(function(){ console.log('Could not connect'); });
}
render() {
return (
<div/>
);
}
}
export default Dashboard;
Generally, when using SignalR, we will create the ChatHub.cs, which contains the send/receive method. In the client side, we will declare a proxy to reference the hub and connect the hub, then, we can call the hub's send/receive method to transfer the message. But from your code, I didn't find where you call the "SendMessageToAll()" method, so the message will not send. Please check your code.
Here are some tutorials about using SignalR, you can check them:
Chat Application Using ASP.NET, ReactJS, Web API, SignalR and Gulp
Tutorial: Real-time chat with SignalR 2
I have a little app that gets sensor data and i want to use mqtt to distribute them. I've found this package on npm called MQTT, with this i can make a client in the browser, if i'm using an http insecure connection it works fine but when i use https i get an error in the create-react-app development server saying that this:
this.client = mqtt.connect();
It's an 'Insecure operation', someone had this problem or know any solution?
Also, in the wiki there is not an entry for a secure connection or something similar.
EDIT: the component code:
import React from 'react';
import mqtt from 'mqtt'
class MqttComponent extends React.Component {
constructor(props) {
super(props);
this.client = mqtt.connect();
this.client.on('connect', () => {
console.log(`connected`);
})
this.client.on('message', (topic, message) => {
let payload = JSON.parse(message);
let payloadKey = topic.substring(1);
console.log('message');
this.props.actualizarPorMensaje(payload, payloadKey);
});
}
componentDidUpdate(prevProps) {
Object.keys(this.props.equipos)
.filter(numeroSerie => !(numeroSerie in prevProps.equipos))
.map(numeroSerie => (
this.client.subscribe(`/${numeroSerie}`)
)
);
}
render() {
return;
}
}
export default MqttComponent;