Wednesday, August 22, 2018

Some gotcha after studying Node/React fullstack course of Stephan Grider

https://www.udemy.com/node-with-react-fullstack-web-development/

Although I am not unfamiliar with these two topics, but I still learn a lot of gotcha in this course.
Especially different consideration when you choose the way to do the project.

  • react
    • use proxy to redirect API to BE during development to prevent use full path ( two server during development)
  • express
    • how to use session and passport to handle login
    • middleware can be use in certain route handler
    • how to handle the route to client in production
      • route to the js , css and image at first
      • any route you don't know , lead to index.html
  • Mongoose
    • subdocument can be used when the document size is enough
    • use updateOne to query and update db at the same time
  • You can build the client code in two ways
    • herokupostinstall after commit code to heroku
    • auto build it in CI , and deploy it to heroku
  • react-form
    • how to use customized component in Field
    • it clean the field after the component is unmount , if you don't wait this behavior , you can set destroyOnUnmount false
    • the way validate the form field is easy to use
    • regular expression of email http://emailregex.com/
  • use localtunnel.com to test webhook during development

Monday, July 30, 2018

Some pain point when I using React Native



Although Airbnb was just sunsetting the usage of React Native on their mobile app. But I still choose it to develop a side project app.

As an Android developer, React Native is very attractive to me. I can construct both iOS and Android app but only maintaining the same code. React is also a cool web technology I study for a while.
 
But after some effort, I found there are some pain point to use it to develop the mobile app.

  • The documentation is poor. When I try to use the KeyboardAvoidingView to handle the keyboard and user input. Not only the official document is limited, I can't find useful info on the Internet. I need to try and error to figure out how the component behave in iOS and Android device.
  • It introduce some effort to use the native feature provided by 3rd party library. The way using 'react native link' to configure iOS and Android is not always reliable. When I used react-native-i18n , the link commend cause the 'jest-haste-map: @providesModule naming collision' issue between the pod package and the node-module package.
  • - The way that facebook handle the issues is disappointing. For example, Chinese input is not handled correctly after v0.54, but it still not fixed in v0.56.

Although there are still such pain points, but it's still a great cross platform framework to build mobile applications. I will keep trying to get familiar with it.

Tuesday, July 10, 2018

use react-native-firebase

To get the push notification or login with facebook SSO in the react native project
It seems that we can not use the pure Expo environment to construct your app with Firebase Web API

react-native-firebase is a light-weight layer sitting on-top of the native Firebase libraries for both iOS and Android

Rather than using the create-react-native-app to create the project.
We need to use react-native-cli to init the project , then the iOS and Android folder will be included.

Then you can run the below command to install the react-native-firebase and link it.

npm install --save react-native-firebase
react-native link react-native-firebase

And you need to update dependency in  the gradle file or podfile .



Here is some configuration you also need to complete:

- Create a Facebook App in the Facebook Developer console , and setup the Android package name or iOS bundle ID there.

- If it's android , the hash value of key you sign the app also need to be added into the Facebook developer console app setting. You can use below command to get the hash value of your default android debug key.

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

- Setup the Facebook App ID into the AndroidManifest or info.plist file

- Create a project in Firebase. Setup the Facebook App ID and Secret in the authentication tab of Firebase console . And add app setting with your Android package name or iOS bundle ID there

- Download the GoogleService-Info.plist into the ios/APP_NAME/ folder (you also need to include it in xcode) or the google-service.json into the android/app/ folder.

Friday, July 6, 2018

GraphQL and Apollo Client



I watch the GraphQL with React: The Complete Developers Guide course by Stephen Grider these days.
There are three major sections:

The first section teach you how to use express and graphql-js to build a GraphQL BE server.
He introduce the package json-server which can build a REST server in a super convenient  manner.
Then we can build a GraphQL server in front of the REST server easily without caring the data source.
This section includes how to write the schema to describe the data type , and how to write the resolver to construct the relation between types. We also need to use resolver to provide mutation to allow client to update/delete the data.

The way to write the schema in graphql-js is not that intuitive to me.
const UserType = new GraphQLObjectType({
  name: 'User',
  fields: {
    id: { type: GraphQLID },
    name: { type: GraphQLString }
  }
})
But just like what Stephen said , keep the resolver and the schema in the same place let developer easy to understand what fields this type can provide.

The second section introduce the way to use apollo-client and React to build a GraphQL client .
It includes:
- How to write the query and mutation in apollo-client, and how the response be used in React.
- How to use date.refetch or refetchQueries to trigger the query after mutation is executed.
- How to use optimisticResponse to predict the response to update the UI before getting the response
- Use dataIdFromObject to prevent refetch the API when you already got updated data in the mutation response

In the last section , it introduce how we can use passport-js to provide authentication in GraphQL.
And some gotcha need to be taken care of when you try to redirect the page once user login their account.

Because I already familiar with React , the React part in this course is too easy to me. But it's still quite helpful to have a full understanding to GraphQL. 

apollo-client actually provides a convenient way to access the GraphQL API, especially it cache the data in the query and prevent you to request same query needed in multiple component. 




Wednesday, June 27, 2018

React Server Side Rendering is cool!



I heard SSR in Syntax podcast for a while .
But I just realized there are so many interesting details after I watch the lesson by Stephen Grider today.
It use React to render the skeleton of components in the server side. 
After the browser load the rendered HTML, it load the client side Javascript.
It will update the DOMs and inject all the dynamic part.

I really like the courses provided by Stephen Grider. They're not only easy to understand but also cover how the mechanism works under neath.

Here are some interesting items of SSR.

- use different Router implementation in Server side vs Client side
- render the html in server side with the data loaded, the loaded data keeped in the store will be also printed in Javascript in the html. Then client bundle javascript will use the store as initial state as client side redux store.
- If the API need to be authenticated. If it's requested in the server side , the cookie need to be take from the HTML request . If the client request the API directly , it should request the API to the render server as a proxy. Because the cookie only works on the same domain.

There are two major benefits why SSR exist.
- It eliminate the time cost of the first API request and DOM rendering in the client side
- Open graph tag provided in server side has better compatibility in social media platform

But the developers really need to evaluate whether it worth , it's far more complicated to implement SSR React than the normal client side React. There are too many stuff need to be taken care.

Monday, February 12, 2018

The way to remount the Android Emulator

Start the emulator by the following command.

emulator -avd <AVD_NAME> -writable-system

Friday, July 21, 2017

Little planets effect (小行星特效)



I got a task to implement this effect recently.
Before it's assigned to me, there was a fragment shader in the codebase to handle this effect.
But the view angle can not be rotated.
So I try to "google" whether there is any information about it.
Then I found this page .
It's a way to project a sphere to a plane.
It's called "stereographic projection";

Φ = asin( cos(c) sin(Φ0) + (y sin(c) cos(Φ0) / r )
λ = λ0 + atan( x sin(c) / (r cos(Φ0) cos(c) - y sin(Φ0) sin(c) )
I can use the above equation to calculate the position correspond to the x,y coordinate on the plane. 
After I adjust the fragment shader by the equation, the user can watch this planet at any angle.
It's quite interesting to try the OpenGL shader, I can generate such amazing results by a few lines of code.

By the way, if you would like to try such kind of effect by your self, you can download  Insta360Player.
If I didn't find a way to implement the little planets effect, I will try to decompile it's apk.


Saturday, July 15, 2017

Android OpenGL Texture memory occupied

I try to solve an interesting memory issue recently.

There is a viewer page in a project I owned recently.
The whole app will be closed without showing the "force close dialog" if we keep entering and leaving that page.
It seems like a memory leak , so I try to use LeakCanary to check it but found nothing related.

Then I try to use the  Memory Monitor  in Android Studio to monitor the memory usage.
But all the memory is released after the GC.

So I can only record the logs during that period and check it line by line.
Then I notice that many process is killed by Activity Manager during that period.
Even a process with OomAdj 0 (contain a foreground activity) is killed too.
It's quite abnormal that Activity Manager will kill so many process when I can't found any app spend lots of memory.
It pops into my mind there is a lesson learned I got in HTC .
In the early version of Android , the memory of a Bitmap can be allocated in the native layer.
Is it the reason it's not watched by the Memory Monitor?

So I try to survey whether there is any command I can use to check the memory usage in native layer.
Then I found the command below.


adb shell dumpsys meminfo <package_name|pid> [-d]

After I execute it, I LOL.
EGL mtrack is fucking high!!



It seems like the memory related to the OpenGL in this page is not released correctly.
After I found the hint, it's much easier to solve this issue.

Monday, May 15, 2017

Practice Line Bot

之前就看過Julian大大分享的 Line Bot 心得
所以大概知道Line Messaging API 運作的方式
不過一直都沒想到比較有意思的題目, 所以就沒寫來玩玩看

最近突然想起, 有時候忘了看女兒的聯絡簿時, 都不知道她們最近教了些什麼東西
於是就決定來寫個聯絡簿的通知小幫手

首先由於我比較熟悉的後端框架是node.js , 跟 J大用的 GO 不同
所以還是另外參考了node上的Line bot 教學文章

在 Line Business Center 申請好帳號之後
需要設定Webhook的網址
也就是 Line 會把一些 event 透過 http 發到該網址

首先npm install linebot --save 之後 ,就能安裝node下的linebot 套件
寫了最基本的程式碼後 , 就能監聽收到訊息時的event
(還得上傳上 Heroku 或類似的服務)

let app = express()
const server = require('http').Server(app)
let bot = LINEBot.create({
  channelID,
  channelSecret,
  channelToken
}, server)

bot.on('message', function(event) {
  console.log(event); //把收到訊息的 event 印出來看看
});

app.use(bot.webhook('/webhook'))

能夠知道使用者發了怎樣的訊息 , 就能利用字串比對的方法
來應答各種不同的回覆訊息

但是我準備嘗試的聯絡簿通知幫手 , 並不需要針對使用者的訊息做回應
而是定期的去爬學校的電子聯絡簿網頁 , 然後發現有新的內容時, 就發給所有使用者

所以在event的部分, 我關心的只有哪個 user 或哪個group 加了我的bot
或移除了bot , 我只要在DB維護這個 userId 跟 groupId的清單
每當有新的聯絡簿內容時 , 就發給他們即可

爬蟲的部分, 我就參考上面連結中使用的 js-crawler 跟 cheerio 兩個套件
去處理學校的聯絡簿網址 , 然後再分別拿到聯絡簿內容與當天的日期
如果發現當天沒有聯絡簿內容(可能老師還沒寫或當天是假日) ,就直接結束
如果有看到內容就將該日期與內容與 DB 內最新的內容做比對
如果日期不同, 就刷新 DB的內容, 並將內容發給所有訂閱的userId / groupId
如果日期相同, 就代表該內容已經發出去過了, 可以略過

雖然兩三年前就加減學過node.js , 但一直也沒有一個題目來認真寫
這次這個題目不僅嘗試了 Line的 Messaging API
另外也第一次在 node.js上使用 mongo db 跟爬蟲
而由於這一些非同步的指令在javascript 上都會使用callback來回傳結果
所以初版寫完之後, 馬上就遇上又臭又長的 callback hell

還好這半年有在Android 上使用 RxJava的經驗
在Javascript上學起 Promise 就較為容易上手
於就再花了些時間把code用Promise 重構 (聽說 Async / Await 更潮, 不過就下次吧)