Firebase Remote Config does not work in React Native - reactjs

No matter what I try, it seems like it is not possible to fetch values from the console with firebase remote config.
I am, "connected" but no values are being fetched besides the default values I have set.
I am using react-native-firebase (v6) https://rnfirebase.io/remote-config/usage
//Package JSON
"react-native": "0.66.0",
"#react-native-firebase/app": "^14.11.1",
"#react-native-firebase/remote-config": "^14.11.1",
Here is my code which is executed on app load:
async componentDidMount() {
const appVersion = DeviceInfo.getVersion();
await remoteConfig().setConfigSettings({
minimumFetchIntervalMillis: 30000,
});
await remoteConfig()
.setDefaults({
is_application_on: true,
min_app_version: appVersion
})
.then(() => remoteConfig().fetchAndActivate())
.then((fetchedRemotely) => {});
let isAppOn = remoteConfig().getBoolean('is_application_on');
let appMinVersion = remoteConfig().getNumber('min_app_version');
this.setState({
isAppOn: isAppOn ? true : false
}, () => {
alert(this.state.isAppOn)
alert(appMinVersion)
})
}
My firebase is connected but remote config is the only module I cannot seem to connect to...
Cheers.

I was able to fix it.
Make sure that you're pointing to the correct google plist file.
In my case it was pointing to the wrong one in xcode, my buildphase script code was off.

Related

MongoDB Realm Functions on React Native

Just started using the Realm MongoDB and i watched this video https://www.youtube.com/watch?v=Evp3xTzWCu4 from MongoDB and followed exactly what he did, but for some the function on the client side is not working. I'm using Expo React Native
I have this simple Realm function
exports = function(arg){
var collection = context.services.get("mongodb-atlas").db("questiondb").collection("questions");
collection.insertOne({name:arg}).then((doc) => {
console.log('Success')
}).catch(error=>console.log(error))
};
When i call it in the real console, it works fine.
This is the front end function
const connectDB = async () => {
const appID = "myapp-ckwfl";
const app = new Realm.App({ id: appID });
const credentials = Realm.Credentials.anonymous();
try {
const user = await app.logIn(credentials);
await user.functions.addQuestion("Myself");
console.log("Logged in");
} catch (error) {
console.log(error);
}
};
I'm getting the 'Logged in' in the console.
I went to check the activity log on the MongoDB atlas and it shows OK to both login and function
However, the function log shows me this message
[ "FunctionError: can't find a table mapping for namespace questiondb.questions" ] { "name": "addQuestion" }
And i have the database 'questiondb' with the collection 'questions'.
What am i missing here?
I ran into a similar error. The problem was that my BSON did not contain an "_id" field. But the BSON validation when saving it allowed me to save the schema like that. But when querying data through graphql I got this exact same error. So the solution was to fix the BSON schema. Even if the BSON schema saves and deploys successfully it can still be that it will not work for graphql.
You can see if your BSON has errors by navigating here:

Axios/Fetch not using next.config.js rewrite

Looking up several examples online, it appears all one would need to do to redirect requests to the backend is to add rewrites to the next.config.js file, and it should work. However, I must be missing or misunderstanding something as this alone doesn't seem to do the trick. Redirecting seems to work if I type the url in the browser, but calls from axios/fetch continue to try to use a path relative to my client. Here are my snippets:
next.config.js
module.exports = {
async rewrites() {
return [
{
source: '/api',
destination: 'http://localhost:3001',
},
]
},
};
components/MyComponent.js
import React, { useEffect } from "react";
import axios from "axios";
function MyComponent({projectName}) {
...
useEffect(() => {
axios.get("/api/project/" + projectName)
.then((res) => {
console.log(res);
});
return;
}, []);
...
};
export default MyComponent;
To clarify, if I hit http://localhost:8001/api/project/Name_of_Project from the browser, I get properly redirected to my server (hosted on port 3001) and receive data I'd expect. However, when I hit my client (http://localhost:8001/Name_of_Project), axios doesn't redirect and tries http://localhost:8001/api/project/Name_of_Project which obviously fails. I also tried the fetch equivalent instead of axios and get the same result.
Is there another step that I need to take? Does the rewrite not work for axios/fetch? I have also seen mentions of the next-http-proxy-middleware package in my search, but I am not sure if this is something that I need to use in conjunction with the rewrite or not.
I appreciate any insight!
EDIT 1:
After doing some more searching, I ran into this post, and discovered that my issue is because I am using relative pathing in my axios call. If I change it to:
axios.get("http://localhost:3001/api/project/" + projectName)
.then((res) => {
console.log(res);
});
then I get my data properly. I suppose this leads me to my next question: is there a way to use relative path alongside the rewrite in the config? I personally think it's a little ugly to have the hostname and port exposed like that (I eventually plan on hosting this app on a FQDN). So if there's anything that can be done about that, I'd love to know!
EDIT 2: Of course the change in my first edit works because I am hitting my server directly! Which is not the desired effect. I want to use the redirect set in the config to go to my api.
Aha! I WAS misunderstanding something. I assumed that the path in the rewrite would reattached my path params for free. This is not the case. A link to the documentation.
The relevant excerpt:
Wildcard Path Matching
To match a wildcard path you can use * after a parameter, for example /blog/:slug* will match /blog/a/b/c/d/hello-world:
module.exports = {
async rewrites() {
return [
{
source: '/blog/:slug*',
destination: '/news/:slug*', // Matched parameters can be used in the destination
},
]
},
}
So my corrected next.config.js:
module.exports = {
async rewrites() {
return [
{
source: '/api/:slug*',
destination: 'http://localhost:3001/api/:slug*',
},
]
},
};

How to get rid of this - message:{'You are not subscribed to this API.'}.?

import React from 'react';
import './App.css';
function App() {
fetch("https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/quickAnswer?q=How%20much%20vitamin%20c%20is%20in%202%20apples%253F", {
"method": "GET",
"headers": {
"x-rapidapi-host": "[host]",
"x-rapidapi-key": "[key]"
}
})
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
return ( <
div className = "App" >
<
form className = 'searchform' >
<
input className = 'search-bar'
type = "text" / >
<
button className = 'search-bar'
type = 'text' > Submit < /button> < /
form > <
/div >
);
}
export default App;
if you have everything set up correct on RapidAPI I would suggest passing the key without using variables because maybe you are passing undefined. For undefined we get exactly the same error.
You have to select a pricing plan, even if it's the free plan. Go to "Pricing" on the page for the API, and select a plan. This fixed the issue for me.
https://api.rakuten.net/Top-Rated/api/e-mail-check-invalid-or-disposable-domain/discussions/9487/keep-getting-this-response-%22You-are-not-subscribed-to-this-API.%22
Be sure that you actually subscribe tothe api on rapid api hub if you aren't subscribed to the api
you're going to get an error message that notifies you don't have an active subscription and your call will not
be successfulbe sure that you actually subscribe tothe api on rapid api hub if you aren't subscribed to the api
you're going to get an error message that notifies you don't have an active subscription and your call will not
be successful
message: you are not subscribed to this api rapidapi
video example
Make sure you select a plan whether it's a free plan or a premium plan.
https://rapidapi.com/tipsters/api/hotels-com-provider/pricing
If you are subscribed to the free plan and still getting this error "message:{'You are not subscribed to this API.'}"
The problem might be related to the .env location. Try placing it inside root of your folder, rather than src folder.
Maybe the problem is with GET, try this. And let me know, if it works or not.
state = {
url:
"<url>",
header: {
"x-rapidapi-host": "<host>",
"x-rapidapi-key": "<key>"
}
};
componentDidMount() {
axios
.post(this.state.url, this.state.header)
.then(res => {
console.log(res.data);
})
.catch(err => console.log("err" + err));
}
For anyone else encountering this issue: the oversight I made was adding 'Bearer ' in from of the RapidAPI key. It should just be the key, without anything in front of it.
This may be stale, but helpful to someone else:
The first thing you want to do is to avoid placing it within .env.
Ensure it works properly within the code snippet (unsafe method) before placing it within .env (current best practice).
For instance, you should first do this:
const options = {
'X-RapidAPI-Key': 'theVeryLenthyKey',
'X-RapidAPI-Host': 'theAPI.p.rapidapi.com'
}
};
Instead of this:
const options = {
'X-RapidAPI-Key': process.env.THE_VARIABLE_NAME_YOU_USED,
'X-RapidAPI-Host': 'theAPI.p.rapidapi.com'
}
};
I got the same response saying {message: you are not subscribed ... but I was, I made sure. So the problem was that it couldn't read from the .env file.
So I used the manual method of directly putting the key in the code while in the development phase, but when I deployed the project I added it in the environment variables of the hosting service and it was working just fine.
If you are passing your key as variables, make sure you place your .env file in root folder (environment variables)
I have fixed this issue by simple directly passing key, like this
export const exerciseOptions = {
method: "GET",
headers: {
"X-RapidAPI-Host": "exercisedb.p.rapidapi.com",
"X-RapidAPI-Key": "xxxxxxxxxxxxxxxxxx",
},
};
don't pass the key through the .env file

Can't get the Generic Sensor API to work in a React app

I'm trying to implement the Generic Sensor API in a React app.
https://www.w3.org/TR/generic-sensor/#the-sensor-interface
I keep getting an error when I try to implement any of the sensors in my code.
For example:
var sensor1 = new AmbientLightSensor();
I get the error: Cannot find name: 'AmbientLightSensor'.
I assume that I need an import statement in my code. All of the examples I've found only include LitElement. I've even tried that but still get the unknown error.
What import statements do I need in my typescript code?
What npm packages do I need?
Below is the typescript code I'm using.
I'm getting a typescript error:
/Users/scoleman/dev/current/bigbrother/src/utility/testAccel.ts(14,24):
Cannot find name 'AmbientLightSensor'. TS2304
export const testAccel = async (
databaseName: string,
) => {
const {state} = await navigator.permissions.query({
name: "ambient-light-sensor"
});
if (state !== "granted") {
console.warn("You haven't granted permission to use the light sensor");
return;
}
const sensor = new AmbientLightSensor();
sensor.addEventListener("reading", () => {
console.log(sensor.illuminance);
});
sensor.addEventListener("error", (err: any) => {
console.error(err);
});
sensor.start();
};
I was able to get these api's running using the polyfill at:
https://github.com/kenchris/sensor-polyfills
This would depend entirely on the browser you are using. I don't think FireFox supports it at the moment so I will focus on Chrome.
Firstly, you might need to be serving your site over HTTPS. It seems like this almost varies from permission to permission and also some are available on a localhost URL no matter what.
Secondly, for Chrome, you have to enable the "Generic Sensor Extra Classes" flag in Chrome at the chrome://flags/#enable-generic-sensor-extra-classes page.
Next, you need to make sure that have permission from the user to use the sensor, then you could actually use it. A snippet that would check that is as follows:
(async function(){
const {state} = await navigator.permissions.query({
name: "ambient-light-sensor"
});
if (state !== "granted") {
console.warn("You haven't granted permission to use the light sensor");
return;
}
const sensor = new AmbientLightSensor();
sensor.addEventListener("reading", () => {
console.log(sensor.illuminance);
});
sensor.addEventListener("error", err => {
console.error(err);
});
sensor.start();
}());

Getting “TypeError: failed to fetch” when sending an email with SendGrid on ReactJS project

I am trying to send email with SendGrid in ReactJS project.
This is my componnet:
//Email.js
import React from 'react'
const sgMail = require('#sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
to: 'aaaaa#gmail.com',
from: 'bbbb#gmail.com',
subject: 'This is a test mail',
text: 'and easy to do anywhere, even with Node.js',
html: '<strong>and easy to do anywhere, even with Node.js</strong>',
};
sgMail.send(msg).catch(error => {alert(error.toString()); });
export const Email= () => (
<h1>Email Sending Page</h1>
)
When I am trying to run the app with "npm start" on localhost, the email is not sent and I got the error message "TypeError: Failed to fetch".
But, if I am using this code:
//Email.js
const sgMail = require('#sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
to: 'aaaaa#gmail.com',
from: 'bbbb#gmail.com',
subject: 'This is a test mail',
text: 'and easy to do anywhere, even with Node.js',
html: '<strong>and easy to do anywhere, even with Node.js</strong>',
};
sgMail.send(msg)
and do this command: "node Email.js" the mail is sent. It works only this way and I cannot understand why.
I tried any solution that I could find but nothing works.
(I tried even to put the api_key hardcoded in the code just for the test and I got the same result).
EDIT
After looking around a bit I found out that you can't use Sendgrid to send email directly from the browser.
Sendgrid won't let you send an email directly using Javascript in the
browser.
You will need to have a server set-up and use the server to send the
email instead (using your favourite back-end framework/language,
Node.js, php, Java, etc.).
The steps for sending a mail will be similar to this:
Write email details in the React application
Send a POST request to
your server endpoint (for example, /sendemail) with the email data
(recipient, title, content, etc.) Receive Email data in the server and
send it to Sendgrid api Here is the official Sendgrid documentation
regarding their CORS policy:
https://sendgrid.com/docs/for-developers/sending-email/cors/
Source: React unable to send email with SendGrid
EDIT 2
If you want to implement Sendgrid without actually building and deploying a server, you can use a simple Firebase function which is free to host.
I know this may look intimidating but in reality its pretty easy. Also I just put this together real quick so if anything doesn't work out for you, shoot me a comment.
Follow steps 1-3 on the getting started page for firebase functions. It is pretty straightforward and you end up with the firebase tools CLI installed.
Navigate to the functions/ folder inside your project on the command line/terminal.
Install the Sendgrid and cors libraries in the functions folder
npm i #sendgrid/mail cors
Add your Sendgrid API key to your firebase environment with the following command in your project:
firebase functions:config:set sendgrid.key="THE API KEY"
Copy this into your functions/index.js file:
const functions = require("firebase-functions");
const cors = require("cors")({ origin: true });
const sgMail = require("#sendgrid/mail");
exports.sendEmail = functions.https.onRequest((req, res) => {
sgMail.setApiKey(functions.config().sendgrid.api);
return cors(req, res, () => {
const { msg } = req.body;
sgMail.send(msg).catch(error => {
alert(error.toString());
});
res.status(200).send(msg);
});
});
Save it and run firebase deploy --only functions on the command line. Your function should now be live at https://us-central1-<project-id>.cloudfunctions.net/sendEmail
Now change your React file to:
//Email.js
import React, { useEffect } from 'react'
export const Email= () => {
useEffect(() => {
const sendEmail = async() => {
const msg = {
to: 'aaaaa#gmail.com',
from: 'bbbb#gmail.com',
subject: 'This is a test mail',
text: 'and easy to do anywhere, even with Node.js',
html: '<strong>and easy to do anywhere, even with Node.js</strong>',
};
const response = await fetch(
'https://us-central1-FIREBASE-PROJECT-ID-HERE.cloudfunctions.net/sendEmail', {
method: 'POST',
body: JSON.stringify(msg),
headers: {
'Content-Type': 'application/json'
}
});
console.log("response", response);
}
sendEmail();
}, []);
return <h1>Email Sending Page</h1>
}
And thats it! You basically have a server side function without making a server and its free!
Feel free to ignore this if you don't feel like putting in the work but if you need any help, let me know.

Resources