//tips
慢性的な寝不足解消になるらしい再生医療関係のエクソソーム注射は効果あるか試してみたいところ。付近で探したが顔の美容関係しかない残念。
//smart contract
各ユーザーのデータベースから文字コンテンツとimage情報を取り出すことに成功した。
文字情報の方をカードの形に表示できるように変換していく。
以前のnotesは以下の形で情報を取得していたのでこちら合わせてみる。
{notes.map(note => (
<Grid item xs={12} md={6} lg={4} key={note.id}>
{/* <NoteCard note={note} handleDelete={handleDelete} /> */}
<NoteCard note={note} />
</Grid>
))}
この形に変形したがNoteCardの読み込みが行われていない。
{ ninja.map((note,index) => {
<div item xs={12} md={6} lg={4} key={index}>
<NoteCard note={note} />
</div>
})}
Returnの中に入っていないことが原因だと気づき、先の各文言表示と混ぜて表示させた。
{ ninja.map((item,index) => {
return (
<div key={index}>
<p> { item.title }</p>
<p>{ item.details } </p>
<p> { item.userid }</p>
<p>{ item.username } </p>
<div xs={12} md={6} lg={4} key={index}>
<NoteCard note={item} />
</div>
</div>
);
})}
これで問題なくfirebaseの内容をカード化して反映できた。
getStaticPropsで取得していなかったカテゴリーの取得も加えた。
pile.category = data.category
データベースの方もcategory項目を付与。これが抜けているとページの読み込み段階でエラーが出る。
error - Error: Error serializing `.ninja[0].category` returned from `getStaticProps` in "/ID/[id]".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.
設定されていないとundefinedとなるのが問題。
ここからはhttp://localhost:3000/ID/1/editのコード内容をlocalhost:3000/ID/1に反映し、それが完了したらhttp://localhost:3000/ID/1/editの方にfirebaseの設定の不足部分を補填していくことにする。
一旦コメントアウト部分を削除してきれいにする。
import React, {useState,useEffect} from 'react'
import firebaseApp from "../../components/firebase"
import firebase from "../../components/firebase2"
import { getStorage, ref,getDownloadURL,uploadBytes } from "firebase/storage";
import { doc, getFirestore } from "firebase/firestore"
import { collection, getDocs,getDoc, query, where,onSnapshot,orderBy,serverTimestamp } from "firebase/firestore"
import { title } from 'process';
import NoteCard from '../../components/Notecard';
//受け取るcontextの内容を編集
export const getStaticPaths = async () => {
let posts = []
const colRef=await collection(firebaseApp, "mydata")
await getDocs(colRef)
.then((snapshot)=>{
snapshot.docs.forEach(doc => {
posts.push(JSON.stringify(doc.data().userid))
});
}).then(()=>console.log(posts))
const paths = posts.map(ninja => {
return {
params: { id:ninja.toString() }
}
})
console.log('paths')
return {
paths,
fallback: false
}
}
//contextは{ params: { id: '2' },などの内容で取得
export const getStaticProps = async (context) => {
console.log(context)
console.log('aa')
let posts = []
const id = parseInt(context.params.id)
const colRef= await collection(firebaseApp, "mydata")
const q = await query(colRef,where("userid","==",id))
await getDocs(q)
.then((snapshot)=>{
snapshot.docs.forEach(doc => {
const data = doc.data()
console.log('data.title')
const pile={}
pile.title = data.title
pile.details = data.details
pile.userid = data.userid
pile.username = data.username
pile.category = data.category
posts.push(pile)
});
})//.then(()=>console.log(posts))
return {
props: { ninja: posts }
}
}
const Details = ({ ninja }) => {
const firestorage = getStorage();
const [image,setImage]=useState('')
//image表示
const gsReference = ref(
firestorage,
"gs://myapp-8e583.appspot.com/"+ninja[0].userid+"/image.jpg"
)
getDownloadURL(gsReference)
.then(url => {
setImage(url)
})
.catch(err => console.log(err))
return (
<div>
{ ninja.map((item,index) => {
return (
<div key={index}>
<p> { item.title }</p>
<p>{ item.details } </p>
<p> { item.userid }</p>
<p>{ item.username } </p>
<div xs={12} md={6} lg={4} key={index}>
<NoteCard note={item} />
</div>
</div>
);
})}
<img src={image} alt="" width="300" height="300"/>
</div>
);
}
export default Details;
コメントアウトを含むものは別のファイルに念の為保存しておいた。
融合の前準備として[id].jsのimport部分から整えていく。
Edit特有の編集部分は[id].jsページには不要なのでhandleDelete={handleDelete}などは削除。
firebaseからimageの引用は別途追加。
<img src={image} alt="" width="300" height="300"/>
アバターを左に寄せ、右にアドレス、名前などを記載できるようにした。
<Grid container spacing={3}>
<Grid item xs={12} md={4} lg={3}>
<img src={image} alt="" width="250" height="250"/>
</Grid>
<Grid item xs={12} md={8} lg={9}>
・・・
handleClickは各idのeditページの飛ぶように変更。
const handleClick = (e) => {
e.preventDefault()
router.push('/ID/'+ninja[0].userid+'/edit')
}
ここでさらにdebankやtwitterのtweetidなどをデータベースに登録しておくことで内容を表示させられるようにする。
Imageは後で丸くくり抜いて表示されるようにする。
pile.tweetId = data.tweetId
オブジェクトの中にtweetId変数を含めたのでこれを抽出して際表示する方法を考えることになる。
<TwitterTweetEmbed
// tweetId={item.id_str}
tweetId={'1501574706423808004'}
/>
を変形させる。
error - Error: Error serializing `.ninja[1].tweetId` returned from `getStaticProps` in "/ID/[id]".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.
が出たので、これはundefinedのものはnullに設定しておく必要がある。
そちらの処理を追加して下記の様子を見る。
{ninja.map((item,index) => (
<div key={index} >
{item.tweetId&&(
<TwitterTweetEmbed
tweetId={item.tweetId}
/>
)}
</div>
))}
値が存在すれば、そのまま格納し、なければnullを入れるようにした。
pile.tweetId = data.tweetId ?data.tweetId:null
これにより無事にtweetの内容がTwitterTweetEmbedのカード形式で表示された。
他の必須記入事項ではないものにもこの三項式を利用しておくことでエラーを防いでおく。
snapshot.docs.forEach(doc => {
const data = doc.data()
console.log('data.title')
const pile={}
//条件式 ? trueの処理 : falseの処理
pile.title = data.title?data.title:null
pile.details = data.details?data.details:null
pile.userid = data.userid
pile.username = data.username
pile.category = data.category?data.category:null
pile.tweetId = data.tweetId ?data.tweetId:null
posts.push(pile)
});
Useridとusernameはどのpost項目にも組み入れるようにしておく。
pile.userid = data.userid
pile.username = data.username
Mediumの入力はデータベースに追加してカード形式で表示させるのでここでは必要ないか。
一方でdebankのdeposit内容はdebankidからfetchしているのでこれは受け渡し可能にしておく。
<Deposits />
ではなく引数を取り、idを受け渡す形に変更。
<Deposits depo={depo}/>
const [depo, setDepo] = useState();
ninja.forEach(Item => {
if(Item.debankid !=null){
// depo = Item.debankid
setDepo(Item.debankid)
console.log(depo)
}
});
export default function Deposits({depo}) {
useEffect(() => {
fetch(
//'https://openapi.debank.com/v1/user/total_balance?id=0xa242fcb2acbb118ea1b6829efe8b7e2087b43986', {
'https://openapi.debank.com/v1/user/total_balance?id='+depo, {
headers:
{
'accept': 'application/json'
}
})
.then(res => res.json())
.then(results => setDebank((results.total_usd_value).toFixed(digit)))
}, [])
こちらの内容で確認。
Depositで下記のエラー。
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'toFixed')
useEffectがこのケースではあっていない気がするので、
.then(()=>console.log('depo'+depo))
を挿入し、depoがどのように渡されているかを確認。
きちんと問題なく数値が渡されているよう。ただ、render数が多すぎるようなので、エラーが出ている。
Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
Renderingはsetするたびに行われるのでさせないように条件付け。
ninja.forEach(Item => {
if(Item.debankid !=null||Item.debankid !=undefined){
if(depo==undefined||depo==null){
// depo = Item.debankid
setDepo(Item.debankid)
console.log('aa')
console.log(depo)
}
}
});
またuseeffectの内容も加工。
useEffect(() => {
console.log('depo'+depo)
if(depo!=undefined||depo!=null){
console.log('depo'+depo)
fetch(
//'https://openapi.debank.com/v1/user/total_balance?id=0xa242fcb2acbb118ea1b6829efe8b7e2087b43986', {
'https://openapi.debank.com/v1/user/total_balance?id='+depo, {
headers:
{
'accept': 'application/json'
}
})
.then(res => res.json())
//.then(()=>console.log('depo'+depo))
//.then(results=>console.log('value'+results.total_usd_value))
.then(results => setDebank((results.total_usd_value).toFixed(digit)))
//.then(results => setDebank((results.total_usd_value)))
}
}, [])
こちらにより意図した形でdebankidからuserのトータル金額を表示させることができた。