How to implement facebook-sdk to gatsby - facebook-sdk-4.0

I'm trying to pull photos from a facebook page and place them on a my gatsby website, but I'm having trouble integrating Facebook SDK so I can use Graph API to grab the data I need. I've tried just getting the url of the photos and used them in img tags, but the photos disappear as I refresh the page.
I used axios to get the data
getFacebookAPI = () => {
let imgArray = []
axios.get('https://graph.facebook.com/v2.7/me?fields=id,albums{photos{images}}&access_token=exampletoken')
.then(response => {
console.log(response)
console.log(response.data.albums.data[0].photos.data)
response.data.albums.data[0].photos.data.map(info =>
imgArray.push(info.images[0].source)
)
})
return imgArray.map(info => <img src={info} alt="facebook" />)
}

Related

Issue with Facebook Pixel in NextJS Website

I am working on a website build with NextJS. I have added the Pixel
to my website, but the pixel is not working correctly. I have added the below code
to my _app.tsx also tried placing the code in [[...pages ]]
<Script
        id="fb-pixel"
        strategy="afterInteractive"
        dangerouslySetInnerHTML={{
          __html: `
            !function(f,b,e,v,n,t,s)
              {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
              n.callMethod.apply(n,arguments):n.queue.push(arguments)};
              if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
              n.queue=[];t=b.createElement(e);t.async=!0;
              t.src=v;s=b.getElementsByTagName(e)[0];
              s.parentNode.insertBefore(t,s)}(window, document,'script',
              'https://connect.facebook.net/en_US/fbevents.js');
              fbq('init', '602606363244718');
              fbq('track', 'PageView');
          `,
        }}
/>
I have also tried with
useEffect(() => {
import('react-facebook-pixel')
.then((x) => x.default)
.then((ReactPixel) => {
ReactPixel.init('XXXXXXXXXXXXXXXXXXXXX') // facebookPixelId
ReactPixel.pageView()
router.events.on('routeChangeComplete', () => {
ReactPixel.pageView()
})
})
}, [router.events])
I have added Google Analytics and Messanger Chat plugins those are working fine, only the Facebook Pixel is not working.
But, sometimes the pixel activates, and sometimes not. Can
Does anybody help me with that?

Next.js SSG page component gets new object from props every time it renders

I'm using Next.js and i want to build simple SSG page, which take immutable data from db on build time and render it to some list of elements. For that purpose i'm using getStaticProps. Here's source code of this page:
import Layout from '../components/Layout'
import utilStyles from '../global-styles/utils.module.css'
import { getSortedPostsData } from '../utils/posts'
import { useMemo } from 'react'
const Home = ({ allPostsData }) => {
const posts = useMemo(() => {
console.log('useMemo log');
return allPostsData.map(({ id, date, title }) => (
<li className={utilStyles.listItem} key={id}>
{title}
<br />
{id}
<br />
{date}
</li>
))
}, [allPostsData])
return (
<Layout home>
<ul className={utilStyles.list}>
{posts}
</ul>
</Layout>
)
}
export const getStaticProps = async () => {
console.log('getStaticProps run')
const allPostsData = await getSortedPostsData()
return {
props: {
allPostsData
}
}
}
export default Home
In production build I can see 'getStaticProps run' log once in console. All required data gets from database and passes to Home component in props. This component renders posts list fine. When i switch to this page in my browser first time I can see exactly one 'useMemo log' in the console. But...
Every time I switch to another page and then back to Home page I see another 'useMemo log' in the browser console too. I'm not understand why this is happening. This page loaded exactly once (not on every page switch). Data for this page is obtained exactly once (in build time). But Next.js passes new array (array with new address) in Home page props every time it renders. Why this is happening and how can i avoid this behavior to memoize my posts list and not render it every time I switch the page?

How to have Cypress go through every page on site to see if there are any console errors and if so, make it known to the user running the test

I want Cypress to go through every page to see on a website to see if there are any console errors and if so, make it known to the user running the test. (I'm thinking it would be useful for CSP checking to see if the site is throwing a console error because of a domain not being whitelisted.)
This package cypress-fail-on-console-error
may make it easier
test
import failOnConsoleError from 'cypress-fail-on-console-error';
failOnConsoleError();
const pages = [ "/page1", "/page2" ]
pages.forEach(page => {
it(`verifies the page ${page}`, () => {
cy.visit(page)
})
})
There's some interesting stuff on Cypress and CSP here
Testing Content-Security-Policy using Cypress ... Almost
You can use a combination of Cypress functionality to achieve this. You could store the list of links in an array of strings, use Cypress Lodash to iterate through each string as a separate test, and use the onBeforeLoad callback within cy.visit() to spy on console.error.
describe('Tests', () => {
// Define links
const links = ['/1', '/2', '/3'...]
// Iterate through the links array using Cypress Lodash
Cypress._.times(links.length, (index) => {
it('validates site loads with no errors', () => {
cy.visit(links[index], {
// set the `onBeforeLoad` callback to save errors as 'error'
onBeforeLoad(win) {
cy.stub(win.console, 'error').as('error');
}
});
// Validate error was not called
cy.get('#error').should('not.have.been.called');
});
});
});
A good deal of this answer was taken from this answer.
If you'd like to be specific about the errors that fail, try catching uncaught:exception
Cypress.on('uncaught:exception', (err) => {
if (err.message.includes('Content Security Policy')) {
return true
} else {
return false // only fail on the above message
}
})
describe('Testing Content Security Policy', () => {
const pages = [ "/page1", "/page2" ]
pages.forEach(page => {
it(`visiting page ${page}`, () => {
cy.visit(page)
})
})
})

Reading and displaying data from a Firestore Document in React Native

Background
I'm trying to build an app which shows a number of stores, in the home screen which is a function component (mind this as I need to use hooks) I have a scroll view which shows different stores.
What I need
When the user presses on one of the stores it should redirect it to a screen which has the information of that specific store. I have built the "store detail" screen but with static info, I want to replace all of that information with data stored in a firestore collection.
Question
How would one go about retrieving data from a Firestore collection in react native, then assigning the data from each document to a separate Touchable Opacity (I know about passing params with react navigation, I just don't know which param to pass when working with Firestore), and then displaying that data in the store detail screen?
Sample code for context
App.js
<NavigationContainer>
<Stack.Navigator initialRouteName={user ? 'Home' : 'Login'}
screenOptions={{cardStyle: { backgroundColor: '#FFFFFF' }}}>
<Stack.Screen name="Home"options={{headerShown: false}}>
{props => <HomeScreen {...props} extraData={user} />}
</Stack.Screen>
<Stack.Screen name="Login" component={LoginScreen} options={{headerShown: false}}/>
<Stack.Screen name="Registration" component={RegistrationScreen} options={{headerShown: false}}/>
<Stack.Screen name="storeDetail" options={{title: ''}}>
{props => <storeDetail {...props} extraData={} />}
</Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
In this file you'll see that I've already called some data (Login and Register pass userData to the Home Screen), however in order to implement that method I depended on the response from the authentication method I was using. I imagine although, I will probably need to pass something as extraData, I understand what I should do, I just don't know how to fill the blank spaces.
Thanks a lot in advance!
First, install the Firebase SDK in your app, so you can make queries to your backend.
I don't know if your sample App.js represents the current state of progress on your app, but I'm going to assume that:
you already have your storeDetail screen built
you know the store's id before navigating to the screen (eg in the HomeScreen)
you pass the storeId as a navigation param when navigating to storeDetail
So in storeSetails screen, you can query Firestore when receiving storeId, and save the result to a state variable on success:
const StoreDetailsScreen = ({ route }) => { // route is passed as a prop by React Navigation
const { storeId } = route.params
const [store, setStore] = useState()
const [loading, setLoading] = useState(true) // show a loading spinner instead of store data until it's available
useEffect(() => {
const fetchQuery = async () => {
const storeData = await firestore()
.collection('stores')
.doc(storeId)
.get() // this queries the database
if (storeData) {
setStore(storeData) // save the data to store state
setLoading(false) // set loading to false
} else {
// something went wrong, show an error message or something
}
}
fetchQuery()
}, [storeId])
if (loading) {
return (
<ActivityIndicator/>
)
}
return (
// ... store details
)
}
Then you can use the data in store to render stuff in your screen
<Text>{store.name}</Text>
<Text>{store.email}</Text>
// ...
More info about how to use Firestore in RN: https://rnfirebase.io/firestore/usage

How To Render Data From Firestore To React Native Component?

I have been trying to render information from my firebase to a react native component. I started by console logging what I have done, the data is being fetched completely fine:
displayAllPlayers(){
dbh.collection('Players').get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
console.log(doc.data().First, doc.data().Last)
})
})
}
I then tried to add this information to my component as follows:
displayAllPlayers(){
dbh.collection('Players').get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
<Player key={doc.data().First} fName={doc.data().First} lName={doc.data().Last} />
})
})
}
render() {
const myPlayers = this.displayAllPlayers()
}
return(
{myPlayers}
)
However, I am unable to see anything on my screen. Any clues why?
thanks
React works a bit differently. You need to save the async call response into the state, and then in the render loop check if the state is there, you loop trough it and print the players.
Here is a similar question that has already answered.
I quote the main points that might be useful for you:
Save the data to state when data loaded
render() {
const myPlayers = this.displayAllPlayers()
let data = doc.data();
this.setState({ data: myPlayers });
}
And then render them as you want:
render() {
let dataUI = this.state.data ? <h1>No Data</h1> : <pre>{JSON.stringify(this.state.data)}</pre>;
return (
<div className="classname">
<h1>... </h1>
<div>
<h1>UI Data</h1>
{dataUI}
</div>
</div>
);
}
Also this is a tutorial about Getting started with Cloud Firestore on React Native. Here is another tutorial a little more explained: Create React Native Firebase CRUD App with Firestore.
I encourage you to check both links to have a better understanding.

Resources