firebase.database(app) arg expects a FirebaseApp instance or undefined - javascript

I'm trying to set data to my realtime database on firebase. I have used the following code.
I am passing my database name as well as the region in my url still getting this error. Is there anyone who know's what is wrong with the code.
Error "firebase.database(app) arg expects a FirebaseApp instance or undefined.Ensure the arg provided is a Firebase app instance; or no args to use the default Firebase app." I have also initialised the firebase config.
Also I am getting the same problem while fetching data.
import {EMPLOYEE_UPDATE,EMPLOYEE_CREATE,} from './types';
import database from '#react-native-firebase/database';
import auth from '#react-native-firebase/auth';
import { firebase } from '#react-native-firebase/app';
import { Actions } from 'react-native-router-flux';
export const employeeUpdate = ({prop,value}) => {
return {
type: EMPLOYEE_UPDATE,
payload: {prop,value},
};
};
export const employeeCreate = ({name,phone,shift}) => {
const {currentUser} = auth();
return (dispatch) =>{
*const ref = database(
'https://managerproject-8924c-default-rtdb.asia-southeast1.firebasedatabase.app/')
.ref(`/users/${currentUser.uid}/employees`);
console.log(ref);
ref.set({name,phone,shift})
.then(()=> {*
console.log('Data set.');
dispatch({type: EMPLOYEE_CREATE });
Actions.employeeList({type: 'reset'});
});
};
};

As Firebase realtime database documentation,
So, the code will be:
import { firebase } from '#react-native-firebase/database';
firebase
.app()
.database('https://managerproject-8924c-default-rtdb.asia-southeast1.firebasedatabase.app/'))
.ref(`/users/${currentUser.uid}/employees`)
.set({name,phone,shift})
.then(() => console.log('Data set.'))
.catch((error) => console.log(error));

Related

Firebase 9 custom thumbnail path doc upload and thumbnail load for avatar

Im trying to rewrite 4 lines of firebase v8 code to work with v9.... but I'm stuck on these 3 lines, even after studying Firebase documentation.... This code is found within a form submit function and taken from one of Shaun Pelling's (the Net Ninja's) Udemy Firebase/React Course.
The code serves a pretty simple purpose:
I'd like to upload the comment to a custom file path within firebase taking in the userId (uid) previously defined as a variable in the filepath. Then upload the file. In my nabber I also have an image being displayed from the url created by the 3rd line of code.
EDIT: First, here's the JSX to which the file originally is uploaded from:
<label>
<span>Upload Profile Thumbnail:</span>
<input
required
type="file"
id="thumbnail"
name="thumbnail"
/>
</label>
the original 4 lines I'm referring to (v8):
const res = await projectAuth.createUserWithEmailAndPassword(email, password)
const uploadPath = `thumbnails/${res.user.uid}/${thumbnail.name}`
const image = await projectStorage.ref(uploadPath).put(thumbnail)
const imageUrl = await image.ref.getDownloadURL()
await res.user.updateProfile({ photoURL: imageUrl })
This is kind of what I've got. (It's a mess I don't don't think it even makes much sense. I'm a bit lost, so if it confuses you as well, please disregard... I just wanted to show I'm trying \(˚☐˚”)/)
import { ref, getDownloadURL, uploadBytesResumable } from 'firebase/storage'
import { updateProfile } from 'firebase/auth'
const uploadPath = `thumbnails/${res.user.uid}/${thumbnail.name}`
const imageUrl = getDownloadURL(ref(storage, image))
const uploadTask = uploadBytesResumable(storageRef, file, metadata )
updateProfile(user, { photoURL: imageUrl})
SIDENOTE:
Oh, 1 little probably much less important sidenote (and more than likely unnecessary), In the v8 example, the thumbnail is uploaded within the signup form, hence the signup function in the first bit of code. In the second example v9, I created a whole new page (only available to signed in users) so that they can upload a thumbnail at a later time. In order to do so, I'm picking up the "user" object from the currentlysignedin user to be able to for instance use the updateProfile function. ie:
// within the v9 code example
const { user } = useAuthContext()
//=======================================
// in the useAuthContext File:
import { AuthContext } from "../CONTEXT/AuthContext.js"
import { useContext } from "react"
export const useAuthContext = () => {
const context = useContext(AuthContext)
return context
}
//=======================================
// in the authContext File:
import { createContext, useReducer, useEffect } from 'react'
import { onAuthStateChanged } from 'firebase/auth'
import { auth } from '../Firebase/config'
export const AuthContext = createContext()
export const authReducer = (state, action) => {
switch (action.type) {
case 'LOGIN':
return { ...state, user: action.payload }
case 'LOGOUT':
return { ...state, user: null }
case 'AUTH_IS_READY':
return { user: action.payload, authIsReady: true }
default:
return state
}
}
export const AuthContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(authReducer, {
user: null,
authIsReady: false
})
useEffect(() => {
const unsub = onAuthStateChanged(auth, user => {
dispatch({ type: 'AUTH_IS_READY', payload: user })
unsub()
})
}, [])
// console.log('AuthContext state:', state)
return (
<AuthContext.Provider value={{ ...state, dispatch }}>
{ children }
</AuthContext.Provider>
)
}
In the V9 code snippet, you are trying to get the download URL before even uploading the image at first place. Also if you don't need to track update progress, use uploadBytes() instead:
import { ref, getDownloadURL, uploadBytesResumable } from 'firebase/storage'
import { updateProfile } from 'firebase/auth'
// pass the path in ref to create a StorageReference
const storageRef = ref(storage, `thumbnails/${res.user.uid}/${thumbnail.name}`)
// upload image, file is a blob here
await uploadBytes(storageRef, file);
const downloadUrl = await getDownloadURL(storageRef);
// this function returns promise too, add await
await updateProfile(user, { photoURL: downloadUrl })

Is there a way to make this asynchronous?

This seems like an easy one and that I'm just missing something obvious, but a little background:
I am making a mock "bug reporting" web app. The app has two types of user: "user" and "engineer". Upon signup the user is assigned a type, and it's saved in a firebase collection "users" under a firebase unique identifier "uid".
Upon login to the web app, a firebase user object for the logged in user is retrieved from firebase. This object has "user.uid" on it.
In order to grab the user type (saved as userType in the firebase document) I need to take that user.uid and send the uid part to a react hook I have made. This hook then fetches the document with that uid and returns the userType.
I've made the following dummy file to demonstrate.
import {React, useEffect, useState} from 'react'
import { useAuthContext } from '../../hooks/useAuthContext'
import { useDocument } from '../../hooks/useDocument'
export default function User() {
const { user } = useAuthContext();
console.log("uid: " + user.uid)
const id = user.uid;
console.log("id: " + id)
let { document, error } = useDocument("users", id)
console.log("userType: " + document.userType)
return (
<div>
</div>
)
}
Now the problem I have is that "user" isn't initalised from Context in time before the program tries to go fetch it, using a uid that, again, isn't initialised in time.
Basically I just need a way to delay using the useDocument hook, but I can't make hooks asynchronous. My async skills aren't my strongest point, to say the least.
Any help is massively appreciated, I've spent so many hours trying to crack this.
EDIT: Upon request, here is the useDocument hook:
import { useEffect, useState } from "react"
import { projectFirestore } from "../firebase/config"
export const useDocument = (collection, id) => {
const [document, setDocument] = useState(null)
const [error, setError] = useState(null)
// realtime document data
useEffect(() => {
const ref = projectFirestore.collection(collection).doc(id)
const unsubscribe = ref.onSnapshot(snapshot => {
// need to make sure the doc exists & has data
if(snapshot.data()) {
setDocument({...snapshot.data(), id: snapshot.id})
setError(null)
}
else {
setError('No such document exists')
}
}, err => {
console.log(err.message)
setError('failed to get document')
})
// unsubscribe on unmount
return () => unsubscribe()
}, [collection, id])
return { document, error }
}

React js how to axios post from outside of component

I am trying to write a function that will handle getting data to and from a server. This function takes the url to contact and uses the token to authorize itself against the server. This function is quite long. I would therefore want every other page in my react app to call this function with the needed url and then let this function handle everything else. I therefore need each page to await this function but I get "Error: Invalid hook call" no matter what I try.
This is the function that handles post requests to the server:
import React, { useEffect, useState, createRef, lazy, useContext } from "react";
import { UserContext } from "./UserContext";
import jwt_decode from "jwt-decode";
import axios from "axios";
export async function getProtectedAsset(url) {
const { user, setUser } = useContext(UserContext);
//If we do not have a token
if (user["userID"] == -1) {
return "Error: No token";
} else {
try {
//Get user data
const token = {
accessToken: user["accessToken"],
email: user["email"],
userID: user["userID"],
};
//Check if accessToken is about to expire (60s mairgain)
if (
Date.now() >=
jwt_decode(token["accessToken"])["exp"] * 1000 - 60000
) {
//Get new token
const res = await axios
.post("http://127.0.0.1:5002/refreshtoken", {
token: user["refreshToken"],
})
.then((res) => {
setUser({
userID: user["userID"],
email: user["email"],
accessToken: res.data["accessToken"],
refreshToken: user["refreshToken"],
accountType: user["accountType"],
});
})
.catch((err) => {
console.error(err);
});
}
//Our token is fresh
else {
const res = await axios
.post(url, token)
.then((promise) => {
return promise.data;
})
.catch((err) => {
console.error(err);
});
}
} catch (error) {
console.log(error);
throw err;
}
}
}
This is the page/component that I try to call this function from:
import React, { useState, useContext, useEffect, useCallback } from "react";
import { UserContext } from "../../UserContext";
import { getProtectedAsset } from "../../getProtectedAsset";
const Settings = () => {
const { user, setUser } = useContext(UserContext);
useEffect(async () => {
try {
let data = await getProtectedAsset("http://127.0.0.1:5002/mypage");
console.log(data);
} catch (error) {
console.error(error.message);
}
}, []);
return <></>;
};
export default Settings;
This gives me the error:
Invalid hook call. Hooks can only be called inside of the body of a
function component. This could happen for one of the following
reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug
and fix this problem.
I have tried everything I can imagine and read different tutorials/guides/docs but still cannot figure out the problem. Usually it is the lack of knowledge, or some thinking mistakes, but I really need help with this one!
Thank you for your help
Its because you are using useContext() hook inside getProtectedAsset() function.
Instead of using useContext inside getProtectedAsset try to pass user as parameter like url to the function.
let data = await getProtectedAsset(url, user);

Have an error with Realtime Database from Firebase

// db.js file
import * as firebase from "firebase/app"
import "firebase/database"
const config = {
apiKey: "" ...
}
const db = firebase.initializeApp(config)
export default db
// App.vue file
import { reactive, onMounted, ref } from 'vue'
import db from "./db.js";
const SendMessage = () => {
const messagesRef = db.database().ref("messages")
if(inputMessage.value === "" || inputMessage.value === null) {
return
}
const message = {
username: state.username,
content: inputMessage.value
}
messagesRef.push(message)
inputMessage.value = ""
}
I try to make a little chat app with Vue.js and Firebase.
So i don't understand because i receive this when i try to send a message :
db_js__WEBPACK_IMPORTED_MODULE_1_.default.database is not a function
at Proxy.SendMessage (App.vue?3dfd:63:1)
I think it's about the import but i try to change for the V9 of firebase but that's didn't work.
Firebase V9 is build in functional aproach. Im working with firestore usually give me a sign if some thing not working.
db.js
import { initializeApp } from 'firebase/app';
import { getDatabase, ref, push, child, serverTimestamp } from 'firebase/database'
const config = {
apiKey: "" ...
}
const firebase = initializeApp(config)
const db = getDatabase()
function addMessage(path, message) {
message.createAt = serverTimestamp() // On database side database will assign current
// timestamp to this field so you will be able to order data
// from newest to oldest for example.
return push(child(ref(db, path)), message)
}
export { addMessage }
App.vue file
import { reactive, onMounted, ref } from 'vue'
import { addMessage } from "./db.js";
const SendMessage = async () => {
if (!inputMessage.value) return
// line above will check are value is "" or null by throwing
// false and using ! in front you changing it to true.
const message = {
username: state.username,
content: inputMessage.value
}
const result = await addMessage('path to data in tree', message)
// async/await will await until data is saved in database and then will do code bellow.
console.log(result.key) // If you await you can read result if result is not void.
inputMessage.value = ""
}
If you use ref() in .vue files make database operations outside of vue files database have same ref() function but they work different. You can allso change name of one function in import line import { ref as dbRef } from 'firebase/database'

Connection to Facebook with React and Firebase

i'm french, sorry for my little english.
I've a problem with Reactjs and Firebase, an error when i want connect with Facebook. I look tutorial in Udemy platform. This is a video for learn React
REBASE: The Firebase endpoint you are trying to listen to must be a string. Instead, got undefined
Parts of code Admin.js :
import React, { Component } from 'react'
import AjouterRecette from './AjouterRecette'
import AdminForm from './AdminForm'
import Login from './Login'
import firebase from 'firebase/app'
import 'firebase/auth'
import base, { firebaseApp } from '../base'
class Admin extends Component {
state = {
uid: null,
chef: null
}
componentDidMount () {
firebase.auth().onAuthStateChanged(user => {
if (user) {
this.handleAuth({ user })
}
})
}
handleAuth = async authData => {
console.log(authData)
const box = await base.fetch(this.props.pseudo, { context: this })
if (!box.chef) {
await base.post(`${this.props.pseudo}/chef`, {
data: authData.user.uid
})
}
this.setState({
uid: authData.user.uid,
chef: box.chef || authData.user.uid
})
}
authenticate = () => {
const authProvider = new firebase.auth.FacebookAuthProvider()
firebaseApp
.auth()
.signInWithPopup(authProvider)
.then(this.handleAuth)
}
...
export default Admin
Thank's
Have a good day.
......................................................................................................................................................................................................................................................................................................................................................................................................
I've got exactly the same problem, probably because I follow the same training as you.
Your error is here :
const box = await base.fetch(this.props.pseudo, { context: this })
because this.props.pseudo is null.
in app.js, in the admin component, write
pseudo={this.props.match.params.pseudo}
and not
pseudo={this.state.pseudo}
and that shoudl work.
regards

Categories