I'm facing a strange issue that I can't seem to figure out. Recently created a brand new project trying to do everything proper with Firebase v9 SDK. Building in Expo 45. All libraries latest. (Note, I have been building with similar stack for a while -- Expo + RN + Firebase)
Setting up new app scaffolding, everything is great. HOWEVER - when I use Expo Go and turn on remote debugging, it launches the debugger but immediately throws a bunch of Firebase errors:
If I goto the debug menu and turn off remote debugging, everything is fine. Anyone run into the same and have a solution?
Update:
I've isolated the issue to where I'm registering the onAuthStateChanged() event. In debug mode only, this code throws the errors:
export default function Navigation({ colorScheme }: { colorScheme: ColorSchemeName }) {
const [bUserAuthenticated, setUserAuthenticated] = useState<Boolean>(false)
useEffect(() => {
try {
const register = async () => {
const app = getApp()
const auth = await getAuth(app)
// const dispatch = useDispatch()
await auth.onAuthStateChanged((user) => {
if (user) {
setUserAuthenticated(true)
// loadUser()
} else {
setUserAuthenticated(false)
}
})
}
register()
} catch (err) {
console.error(`[Navigation.useEffect] ${err}`)
}
}, [])
Again, without running Expo Go in remote debug mode, this works fine. But when running in remote debug mode, it throws the Firebase unhandled promise exception errors.
It looks like there was an issue with the Firebase SDK version I was using (9.8.1). No matter what, whenever it was running in the RN debugger, when getting an instance of any of the modules, it would barf and give an error.
Downgrading to firebase 9.6.1 solved this issue.
Related
I was trying to integrate Google's Firebase Remote config into my Next.js app.
When following Firebase's docs, and just inserted the functions directly into my component's code block, like so:
const remoteConfig = getRemoteConfig(app);
I keep getting the following error when following their documentation:
FirebaseError: Remote Config: Undefined window object. This SDK only supports usage in a browser environment.
I understand that it happens since Nextjs is rendered server-side, so there's no window object yet, so here's my solution:
import {
fetchAndActivate,
getRemoteConfig,
getString,
} from 'firebase/remote-config';
const Home: NextPage<Props> = (props) => {
const [title, setTitle] = useState<string | null>('Is It True?');
useEffect(() => {
if (typeof window !== 'undefined') {
const remoteConfig = getRemoteConfig(app);
remoteConfig.settings.minimumFetchIntervalMillis = 3600000;
fetchAndActivate(remoteConfig)
.then(() => {
const titleData = getString(remoteConfig, 'trueOrFalse');
setTitle(titleData);
})
.catch((err) => {
console.log(err);
});
}
});
return <h1>{title}</h1>}
Basically, the important part is the if statement that checks if the window object exists, then it execute the Remote Config functions according to Firebase documents.
Also, it worked outside a useEffect, but I think that's probably a bad idea to leave it outside, maybe even it should have a dependency, can't think of one at the moment.
I need to compile a smart contract inside a firebase function. I am using solc "solc": "^0.8.13", in my package.json.
Code of the firebase function responsible to create the contact is;
const functions = require("firebase-functions");
const admin = require('firebase-admin');
const solc = require('solc');
const fs = require("fs");
const Web3 = require('web3');
exports.createSC = functions.https.onCall((data, context) => {
if (!context.auth) return { data: data, status: 'error', code: 401, message: 'Not signed in' }
return new Promise((resolve, reject) => {
admin.auth().getUser(data.owner)
.then(userRecord => {
//below function compiles the contract and returns abi/binary code etc
let contract = instantiateContract('sources/SnaphashToken.sol');
//use web3 to actually deploy contract
let web3;
//...code emitted...
resolve(contractDeployResult)
})
.catch(error => {
console.error('Error fetching user data:', error)
reject({ status: 'error', code: 500, error })
})
});
})
this works perfectly well when deployed on functions simulator locally but when deployed on firebase cloud I get this exception;
i functions: updating Node.js 16 function ethereum-createSC(us-central1)...
Function failed on loading user code. This is likely due to a bug in the user code. Error message: Error: please examine your function logs to see the error cause: https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs. Additional troubleshooting documentation can be found at https://cloud.google.com/functions/docs/troubleshooting#logging. Please visit https://cloud.google.com/functions/docs/troubleshooting for in-depth troubleshooting documentation.
Functions deploy had errors with the following functions:
ethereum-createSC(us-central1)
When I comment out const solc = require('solc') in my function, it deploys without problems. I really need to be able to deploy smart contracts after modifying based on user input and would appreciate a help on it
I found out that the subject function was causing deployment error because of Error: memory limit exceeded. I was able to see that after I checked detailed logs of the functions with firebase functions:log
2022-05-27T17:09:27.384860094Z E ethereum-createNft: Function cannot be initialized. Error: memory limit exceeded.
In order to fix this issue, I increased memory for the function from default 256MB to 1GB and timeoutSeconds from default 60 seconds to 120 seconds
exports.createNft = functions.runWith({memory:'1GB',timeoutSeconds:120}).https.onCall((data, context) => {
..code here..
});
And then deployment was successful
When I start the functions locally (firebase serve --only functions), it can read & write the Firestore data but when it comes to send the push notification it fails with the following error. It was working since yesterday. Today i updated my MacOS to Big Sur and then it stopped working.
Unauthorized Error 401 An error occurred when trying to authenticate
to the FCM servers. Make sure the credential used to authenticate
this SDK has the proper permissions. See
https://firebase.google.com/docs/admin/setup for setup instructions.
Following is the function that tries to send the notification:
exports.test = functions.https.onRequest(async (req, response) => {
var data = {};
const token = await util.getTokenByEmail('demouser#gmail.com');
let payload = {}, notiData = {}, notification = {}
notification.title = notiData.title = `Test msg`;
notification.body = `Test msg`;
notiData.message = `Test msg`;
payload.notification = notification;
payload.data = notiData;
try {
await admin.messaging().sendToDevice(token, payload);
} catch (e) {
console.log(`Error: ${e}`); // Unauthorized Error 401
data.error = e;
}
response.status(200).json({ data: data });
});
I followed the steps given here and also set the GOOGLE_APPLICATION_CREDENTIALS.
export GOOGLE_APPLICATION_CREDENTIALS="Volumes/demo/Firebase/key.json"
I am downloading the key.json from the Firebase -> Settings -> Service Accounts.
It turned out that, I was setting the GOOGLE_APPLICATION_CREDENTIALS only for that terminal session. Once I set the path to $HOME/.zshrc, it started working. Thanks for your time and help.
I am new to react native and firebase and am trying to create an app that uses firebase to send background notifications within iOS.
When I run my app I seem to get the following error message and my app won't run.
TypeError: (0, _app2.messaging) is not a function. (In '(0, _app2.messaging)()', '(0, _app2.messaging)' is undefined)
Here is my firebase code.
import {name as appName} from './app.json';
import {AppRegistry} from 'react-native';
import {messaging} from '#react-native-firebase/app';
requestUserPermission = async () => {
const authStatus = await messaging().requestPermission();
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (enabled) {
console.log('Authorization status:', authStatus);
}
};
// Register background handler
messaging().setBackgroundMessageHandler(async (remoteMessage) => {
console.log('Messaage handled in the background!', remoteMessage);
});
HeadlessCheck = ({ isHeadless }) => {
if (isHeadless) {
// App has beeen launched in the background by iOS, ignore
return null;
}
return <App />;
}
AppRegistry.registerComponent(appName, () => HeadlessCheck);
I might be writing my firebase code wrong as I am new to firebase and I'm still unsure what I am doing and am simply trying to follow a few online tutorials.
I did google this problem but not one seems to be having it. I tried to delete my node_modules folder and ran yarn again but this didn't fix the problem.
Seems that messaging does not exist, I noticed you are importing messaging from #react-native-firebase/app. Following the docs (https://rnfirebase.io/messaging/usage) looks like you need a different module.
Installing the messaging module:
# Install the messaging module
yarn add #react-native-firebase/messaging
# If you're developing your app using iOS, run this command
cd ios/ && pod install
Importing messaging for usage
import messaging from '#react-native-firebase/messaging';
I'm trying to implement Nuxt with SSR in Firebase hosting (using Firebase functions), but after my function is triggered I keep getting an '504 timed out waiting for function to respond'.
My Firebase function:
const functions = require("firebase-functions");
const { Nuxt } = require("nuxt");
const express = require("express");
const app = express();
const config = {
dev: false,
buidlDir: 'src',
build: {
publicPath: '/'
}
};
const nuxt = new Nuxt(config);
function handleRequest(req, res){
console.log('handling request');
//res.set('Cache-Control', 'public, max-age=600, s-maxage=1200')
nuxt.renderRoute('/')
.then(result => {
console.log('result: ' + result.html);
res.send(result.html);
})
.catch(e => {
res.send(e);
console.log(e);
})
}
app.get('*', handleRequest);
exports.ssrApp = functions.https.onRequest(app);
I also tried with:
function handleRequest(req, res) {
console.log("log3");
res.set("Cache-Control", "public, max-age=300, s-maxage=600");
return new Promise((resolve, reject) => {
nuxt.render(req, res, promise => {
promise.then(resolve).catch(reject);
});
});
}
I also have node vs8 as default for my functions because I read that that could give problems. :
"engines": {
"node": "8"
},
But with the same result. My function is being triggered but it always times out, btw: I have this problem serving locally and when trying to deploy to Firebase itself.
Let me know if you need more information/code to try to help and see what the problem could be.
First, if you want to find out what caused it, use debug option.
Second, if you face the timeout error, check the path is valid.
If you success build Nuxt and nuxt.render, the error is processed by Nuxt, and Nuxt show this error page.
In other words, if you don't see Nuxt error page, the cause may be not related with Nuxt.
I also stuck 4 hours due to timeout error, and I finally found out the cause was the contents of publicPath.
Please check these 2 things.
buidlDir is valid ?
The path of buildDir is valid ? You should check .nuxt folder is deployed to your cloud functions successfully.
publicPath contents is uploaded successfully?
The builded contents in .nuxt/dist must be uploaded to Firebase Hosting. You should check it manually.
Type URL to address bar ex) https://test.firebaseapp.com/path/to/file.js
Finally, I post a URL of
my sample project, using Nuxt and Firebase.
I also stucked like you and it made me rally tired. I'm really happy if this answer helps someone like me.
PS: When you build Nuxt in functions folder, nuxt start is failed. Be careful. In my project, I build it in root, and when deploy, I copied it.
Nuxt SSR with Firebase Integration
I got the same problem because Nuxt is not ready yet (promise is undefined)
So you can try to add nuxt.ready() after new Nuxt()
Example:
const functions = require('firebase-functions');
const express = require('express');
const { Nuxt } = require('nuxt');
const config = {
dev: false
// Your config
};
const nuxt = new Nuxt(config);
const app = express();
nuxt.ready(); // <---------- Add this!
async function handleRequest(req, res) {
res.set('Cache-Control', 'public, max-age=1, s-maxage=1');
await nuxt.render(req, res);
}
app.get('*', handleRequest);
app.use(handleRequest);
exports.ssrApp = functions.https.onRequest(app);
Ref: https://github.com/nuxt/nuxt.js#using-nuxtjs-programmatically